@salesforce/lds-runtime-aura 1.443.0 → 1.445.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 +453 -213
- package/dist/types/aura-utils.d.ts +40 -4
- package/dist/types/fetch-service-descriptors/jwt-authorized-fetch-service.d.ts +3 -0
- package/dist/types/network-sfap.d.ts +1 -0
- package/dist/types/parameterized-sfap-jwt-aura-resolver.d.ts +34 -0
- package/dist/types/request-interceptors/jwt-parameterization.d.ts +50 -0
- package/dist/types/response-interceptors/{lex-runtime-auth-expiration-redirect.d.ts → lex-runtime-session-expiration.d.ts} +2 -2
- package/dist/types/sfap-jwt-mint-params.d.ts +80 -0
- package/package.json +45 -45
package/dist/ldsEngineCreator.js
CHANGED
|
@@ -24,7 +24,7 @@ import { findExecutableOperation, buildGraphQLInputExtension, addTypenameToDocum
|
|
|
24
24
|
import { print, resolveAndValidateGraphQLConfig, toGraphQLErrorResponse } from 'force/luvioOnestoreGraphqlParser';
|
|
25
25
|
import getServices, { setServices } from 'force/luvioServiceProvisioner1';
|
|
26
26
|
import { assertIsValid, JsonSchemaViolationError, MissingRequiredPropertyError } from 'force/luvioJsonschemaValidate5';
|
|
27
|
-
import { dispatchGlobalEvent, executeGlobalControllerRawResponse } from 'aura';
|
|
27
|
+
import { dispatchGlobalEvent as dispatchGlobalEvent$1, 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';
|
|
29
29
|
import { ThirdPartyTracker } from 'instrumentation:thirdPartyTracker';
|
|
30
30
|
import { markStart, markEnd, counter, registerCacheStats, perfStart, perfEnd, registerPeriodicLogger, interaction, timer, mark } from 'instrumentation/service';
|
|
@@ -137,7 +137,9 @@ function buildSubscribableResult$1(result, subscribe, refresh) {
|
|
|
137
137
|
}
|
|
138
138
|
function resolvedPromiseLike$2(result) {
|
|
139
139
|
if (isPromiseLike$2(result)) {
|
|
140
|
-
return result.then(
|
|
140
|
+
return result.then(
|
|
141
|
+
(nextResult) => nextResult
|
|
142
|
+
);
|
|
141
143
|
}
|
|
142
144
|
return {
|
|
143
145
|
then: (onFulfilled, _onRejected) => {
|
|
@@ -154,7 +156,9 @@ function resolvedPromiseLike$2(result) {
|
|
|
154
156
|
}
|
|
155
157
|
function rejectedPromiseLike$2(reason) {
|
|
156
158
|
if (isPromiseLike$2(reason)) {
|
|
157
|
-
return reason.then(
|
|
159
|
+
return reason.then(
|
|
160
|
+
(nextResult) => nextResult
|
|
161
|
+
);
|
|
158
162
|
}
|
|
159
163
|
return {
|
|
160
164
|
then: (_onFulfilled, onRejected) => {
|
|
@@ -173,8 +177,9 @@ function isPromiseLike$2(x) {
|
|
|
173
177
|
return typeof x?.then === "function";
|
|
174
178
|
}
|
|
175
179
|
function stableJSONStringify$2(node) {
|
|
176
|
-
|
|
177
|
-
|
|
180
|
+
const withToJSON = node;
|
|
181
|
+
if (withToJSON && typeof withToJSON.toJSON === "function") {
|
|
182
|
+
node = withToJSON.toJSON();
|
|
178
183
|
}
|
|
179
184
|
if (node === void 0) {
|
|
180
185
|
return;
|
|
@@ -200,11 +205,12 @@ function stableJSONStringify$2(node) {
|
|
|
200
205
|
if (node === null) {
|
|
201
206
|
return "null";
|
|
202
207
|
}
|
|
203
|
-
const
|
|
208
|
+
const record = node;
|
|
209
|
+
const objKeys = keys$2(record).sort();
|
|
204
210
|
out = "";
|
|
205
211
|
for (i = 0; i < objKeys.length; i++) {
|
|
206
212
|
const key = objKeys[i];
|
|
207
|
-
const value = stableJSONStringify$2(
|
|
213
|
+
const value = stableJSONStringify$2(record[key]);
|
|
208
214
|
if (!value) {
|
|
209
215
|
continue;
|
|
210
216
|
}
|
|
@@ -234,6 +240,19 @@ var HttpStatusCode$1 = /* @__PURE__ */ ((HttpStatusCode2) => {
|
|
|
234
240
|
HttpStatusCode2[HttpStatusCode2["GatewayTimeout"] = 504] = "GatewayTimeout";
|
|
235
241
|
return HttpStatusCode2;
|
|
236
242
|
})(HttpStatusCode$1 || {});
|
|
243
|
+
function getFetchResponseFromAuraError(err2) {
|
|
244
|
+
const auraError = err2;
|
|
245
|
+
if (auraError.data !== void 0 && auraError.data.statusCode !== void 0) {
|
|
246
|
+
const data = auraError.data;
|
|
247
|
+
if (auraError.id !== void 0) {
|
|
248
|
+
data.id = auraError.id;
|
|
249
|
+
}
|
|
250
|
+
return new FetchResponse(data.statusCode, data);
|
|
251
|
+
}
|
|
252
|
+
return new FetchResponse(500, {
|
|
253
|
+
error: err2?.message
|
|
254
|
+
});
|
|
255
|
+
}
|
|
237
256
|
async function coerceResponseToFetchResponse(response) {
|
|
238
257
|
const { status } = response;
|
|
239
258
|
const responseHeaders = {};
|
|
@@ -286,9 +305,10 @@ function deepFreeze(value) {
|
|
|
286
305
|
deepFreeze(value[i]);
|
|
287
306
|
}
|
|
288
307
|
} else {
|
|
289
|
-
const
|
|
308
|
+
const record = value;
|
|
309
|
+
const keys$1 = keys$2(record);
|
|
290
310
|
for (let i = 0, len = keys$1.length; i < len; i += 1) {
|
|
291
|
-
deepFreeze(
|
|
311
|
+
deepFreeze(record[keys$1[i]]);
|
|
292
312
|
}
|
|
293
313
|
}
|
|
294
314
|
freeze(value);
|
|
@@ -362,7 +382,7 @@ let NetworkCommand$1 = class NetworkCommand extends BaseCommand {
|
|
|
362
382
|
async afterRequestHooks(_options) {
|
|
363
383
|
}
|
|
364
384
|
};
|
|
365
|
-
function buildServiceDescriptor$
|
|
385
|
+
function buildServiceDescriptor$q() {
|
|
366
386
|
return {
|
|
367
387
|
type: "networkCommandBaseClass",
|
|
368
388
|
version: "1.0",
|
|
@@ -388,7 +408,7 @@ class AuraNetworkCommand extends NetworkCommand$1 {
|
|
|
388
408
|
);
|
|
389
409
|
}
|
|
390
410
|
coerceAuraErrors(auraErrors) {
|
|
391
|
-
return
|
|
411
|
+
return new UserVisibleError(getFetchResponseFromAuraError(auraErrors[0]));
|
|
392
412
|
}
|
|
393
413
|
/**
|
|
394
414
|
* Customize how non-2xx fetch fallback responses are converted into errors.
|
|
@@ -468,7 +488,7 @@ class AuraNetworkCommand extends NetworkCommand$1 {
|
|
|
468
488
|
return resolvedPromiseLike$2(err$1(toError("Aura/Fetch network services not found")));
|
|
469
489
|
}
|
|
470
490
|
}
|
|
471
|
-
function buildServiceDescriptor$
|
|
491
|
+
function buildServiceDescriptor$p() {
|
|
472
492
|
return {
|
|
473
493
|
type: "auraNetworkCommandBaseClass",
|
|
474
494
|
version: "1.0",
|
|
@@ -510,7 +530,9 @@ function buildSubscribableResult(result, subscribe, refresh) {
|
|
|
510
530
|
}
|
|
511
531
|
function resolvedPromiseLike$1(result) {
|
|
512
532
|
if (isPromiseLike$1(result)) {
|
|
513
|
-
return result.then(
|
|
533
|
+
return result.then(
|
|
534
|
+
(nextResult) => nextResult
|
|
535
|
+
);
|
|
514
536
|
}
|
|
515
537
|
return {
|
|
516
538
|
then: (onFulfilled, _onRejected) => {
|
|
@@ -527,7 +549,9 @@ function resolvedPromiseLike$1(result) {
|
|
|
527
549
|
}
|
|
528
550
|
function rejectedPromiseLike$1(reason) {
|
|
529
551
|
if (isPromiseLike$1(reason)) {
|
|
530
|
-
return reason.then(
|
|
552
|
+
return reason.then(
|
|
553
|
+
(nextResult) => nextResult
|
|
554
|
+
);
|
|
531
555
|
}
|
|
532
556
|
return {
|
|
533
557
|
then: (_onFulfilled, onRejected) => {
|
|
@@ -573,7 +597,10 @@ function deepEquals$1(x, y) {
|
|
|
573
597
|
}
|
|
574
598
|
for (let i = 0; i < xkeys.length; ++i) {
|
|
575
599
|
const key = xkeys[i];
|
|
576
|
-
if (!deepEquals$1(
|
|
600
|
+
if (!deepEquals$1(
|
|
601
|
+
x[key],
|
|
602
|
+
y[key]
|
|
603
|
+
)) {
|
|
577
604
|
return false;
|
|
578
605
|
}
|
|
579
606
|
}
|
|
@@ -1018,144 +1045,6 @@ function mergeCacheControlConfigs(baseConfig, overrides) {
|
|
|
1018
1045
|
};
|
|
1019
1046
|
}
|
|
1020
1047
|
|
|
1021
|
-
let AuraCacheControlCommand$1 = class AuraCacheControlCommand extends CacheControlCommand {
|
|
1022
|
-
constructor(services) {
|
|
1023
|
-
super(services);
|
|
1024
|
-
this.services = services;
|
|
1025
|
-
this.actionConfig = {
|
|
1026
|
-
background: false,
|
|
1027
|
-
hotspot: true,
|
|
1028
|
-
longRunning: false,
|
|
1029
|
-
storable: false
|
|
1030
|
-
};
|
|
1031
|
-
this.networkPreference = "aura";
|
|
1032
|
-
}
|
|
1033
|
-
get fetchParams() {
|
|
1034
|
-
throw new Error(
|
|
1035
|
-
"Fetch parameters must be specified when using HTTP transport on an Aura adapter"
|
|
1036
|
-
);
|
|
1037
|
-
}
|
|
1038
|
-
shouldUseAuraNetwork() {
|
|
1039
|
-
return this.services.auraNetwork !== void 0 && (this.networkPreference === "aura" || !this.services.fetch);
|
|
1040
|
-
}
|
|
1041
|
-
shouldUseFetch() {
|
|
1042
|
-
return this.services.fetch !== void 0 && (this.networkPreference === "http" || !this.services.auraNetwork);
|
|
1043
|
-
}
|
|
1044
|
-
requestFromNetwork() {
|
|
1045
|
-
if (this.shouldUseAuraNetwork()) {
|
|
1046
|
-
return this.convertAuraResponseToData(
|
|
1047
|
-
this.services.auraNetwork(this.endpoint, this.auraParams, this.actionConfig),
|
|
1048
|
-
(errs) => this.coerceAuraErrors(errs)
|
|
1049
|
-
);
|
|
1050
|
-
} else if (this.shouldUseFetch()) {
|
|
1051
|
-
const params = this.fetchParams;
|
|
1052
|
-
try {
|
|
1053
|
-
return this.convertFetchResponseToData(this.services.fetch(...params));
|
|
1054
|
-
} catch (reason) {
|
|
1055
|
-
return resolvedPromiseLike$2(err$1(toError(reason)));
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1058
|
-
return resolvedPromiseLike$2(err$1(toError("Aura/Fetch network services not found")));
|
|
1059
|
-
}
|
|
1060
|
-
coerceAuraErrors(auraErrors) {
|
|
1061
|
-
return toError(auraErrors[0]);
|
|
1062
|
-
}
|
|
1063
|
-
async coerceError(errorResponse) {
|
|
1064
|
-
return toError(errorResponse.statusText);
|
|
1065
|
-
}
|
|
1066
|
-
processAuraReturnValue(auraReturnValue) {
|
|
1067
|
-
return ok$2(auraReturnValue);
|
|
1068
|
-
}
|
|
1069
|
-
processFetchReturnValue(json) {
|
|
1070
|
-
return ok$2(json);
|
|
1071
|
-
}
|
|
1072
|
-
convertAuraResponseToData(responsePromise, coerceError) {
|
|
1073
|
-
return responsePromise.then((response) => {
|
|
1074
|
-
return this.processAuraReturnValue(response.getReturnValue());
|
|
1075
|
-
}).finally(() => {
|
|
1076
|
-
try {
|
|
1077
|
-
this.afterRequestHooks({ statusCode: 200 });
|
|
1078
|
-
} catch {
|
|
1079
|
-
}
|
|
1080
|
-
}).catch((error) => {
|
|
1081
|
-
if (!error) {
|
|
1082
|
-
return err$1(toError("Failed to get error from response"));
|
|
1083
|
-
}
|
|
1084
|
-
if (!error.getError) {
|
|
1085
|
-
return err$1(toError(error));
|
|
1086
|
-
}
|
|
1087
|
-
const actionErrors = error.getError();
|
|
1088
|
-
if (actionErrors.length > 0) {
|
|
1089
|
-
return err$1(coerceError(actionErrors));
|
|
1090
|
-
}
|
|
1091
|
-
return err$1(toError("Error fetching component"));
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
convertFetchResponseToData(response) {
|
|
1095
|
-
return response.then(
|
|
1096
|
-
(response2) => {
|
|
1097
|
-
if (response2.ok) {
|
|
1098
|
-
return response2.json().then(
|
|
1099
|
-
(json) => {
|
|
1100
|
-
return this.processFetchReturnValue(json);
|
|
1101
|
-
},
|
|
1102
|
-
(reason) => err$1(toError(reason))
|
|
1103
|
-
).finally(() => {
|
|
1104
|
-
try {
|
|
1105
|
-
this.afterRequestHooks({ statusCode: response2.status });
|
|
1106
|
-
} catch {
|
|
1107
|
-
}
|
|
1108
|
-
});
|
|
1109
|
-
} else {
|
|
1110
|
-
return this.coerceError(response2).then((coercedError) => {
|
|
1111
|
-
return err$1(coercedError);
|
|
1112
|
-
}).finally(() => {
|
|
1113
|
-
try {
|
|
1114
|
-
this.afterRequestHooks({ statusCode: response2.status });
|
|
1115
|
-
} catch {
|
|
1116
|
-
}
|
|
1117
|
-
});
|
|
1118
|
-
}
|
|
1119
|
-
},
|
|
1120
|
-
(reason) => err$1(toError(reason))
|
|
1121
|
-
);
|
|
1122
|
-
}
|
|
1123
|
-
};
|
|
1124
|
-
class AuraResourceCacheControlCommand extends AuraCacheControlCommand$1 {
|
|
1125
|
-
constructor(services) {
|
|
1126
|
-
super(services);
|
|
1127
|
-
this.services = services;
|
|
1128
|
-
}
|
|
1129
|
-
readFromCache(cache) {
|
|
1130
|
-
const data = cache.get(this.buildKey())?.value;
|
|
1131
|
-
if (data === void 0) {
|
|
1132
|
-
return resolvedPromiseLike$2(err$1(new Error("Failed to find data in cache")));
|
|
1133
|
-
}
|
|
1134
|
-
return resolvedPromiseLike$2(ok$2(data));
|
|
1135
|
-
}
|
|
1136
|
-
writeToCache(cache, networkResult) {
|
|
1137
|
-
if (networkResult.isOk()) {
|
|
1138
|
-
cache.set(this.buildKey(), {
|
|
1139
|
-
value: networkResult.value,
|
|
1140
|
-
metadata: {
|
|
1141
|
-
cacheControl: this.buildCacheControlMetadata(networkResult.value)
|
|
1142
|
-
}
|
|
1143
|
-
});
|
|
1144
|
-
}
|
|
1145
|
-
return resolvedPromiseLike$2(void 0);
|
|
1146
|
-
}
|
|
1147
|
-
buildKey() {
|
|
1148
|
-
return `{"endpoint":${this.endpoint},"params":${stableJSONStringify$2(this.auraParams)}}`;
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
function buildServiceDescriptor$p() {
|
|
1152
|
-
return {
|
|
1153
|
-
type: "auraResourceCacheControlCommand",
|
|
1154
|
-
version: "1.0",
|
|
1155
|
-
service: AuraResourceCacheControlCommand
|
|
1156
|
-
};
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
1048
|
class AuraCacheControlCommand extends CacheControlCommand {
|
|
1160
1049
|
constructor(services) {
|
|
1161
1050
|
super(services);
|
|
@@ -1441,16 +1330,16 @@ class NetworkCommand extends BaseCommand {
|
|
|
1441
1330
|
}
|
|
1442
1331
|
}
|
|
1443
1332
|
function isAbortableCommand(command) {
|
|
1444
|
-
return "isAbortableCommand" in command && command.isAbortableCommand === true;
|
|
1333
|
+
return !!command && typeof command === "object" && "isAbortableCommand" in command && command.isAbortableCommand === true;
|
|
1445
1334
|
}
|
|
1446
1335
|
function hasFetchParams(command) {
|
|
1447
|
-
return command && typeof command === "object" && "fetchParams" in command;
|
|
1336
|
+
return !!command && typeof command === "object" && "fetchParams" in command;
|
|
1448
1337
|
}
|
|
1449
1338
|
function createAbortableDecorator(command, options) {
|
|
1450
|
-
|
|
1339
|
+
const signal = options?.signal;
|
|
1340
|
+
if (!signal || !(signal instanceof AbortSignal)) {
|
|
1451
1341
|
return command;
|
|
1452
1342
|
}
|
|
1453
|
-
const { signal } = options;
|
|
1454
1343
|
if (isAbortableCommand(command)) {
|
|
1455
1344
|
if (process.env.NODE_ENV !== "production") {
|
|
1456
1345
|
console.warn(
|
|
@@ -1461,14 +1350,15 @@ function createAbortableDecorator(command, options) {
|
|
|
1461
1350
|
}
|
|
1462
1351
|
if (!hasFetchParams(command)) {
|
|
1463
1352
|
if (process.env.NODE_ENV !== "production") {
|
|
1353
|
+
const commandName = typeof command === "object" && command !== null ? command.constructor.name : typeof command;
|
|
1464
1354
|
console.warn(
|
|
1465
|
-
`Command ${
|
|
1355
|
+
`Command ${commandName} does not support fetch operations. AbortSignal will be ignored.`
|
|
1466
1356
|
);
|
|
1467
1357
|
}
|
|
1468
1358
|
return command;
|
|
1469
1359
|
}
|
|
1470
1360
|
try {
|
|
1471
|
-
|
|
1361
|
+
const handler = {
|
|
1472
1362
|
get(target, prop, receiver) {
|
|
1473
1363
|
if (prop === "isAbortableCommand") {
|
|
1474
1364
|
return true;
|
|
@@ -1477,8 +1367,8 @@ function createAbortableDecorator(command, options) {
|
|
|
1477
1367
|
return signal;
|
|
1478
1368
|
}
|
|
1479
1369
|
if (prop === "fetchParams") {
|
|
1480
|
-
const originalFetchParams = target
|
|
1481
|
-
const isInternal = target
|
|
1370
|
+
const originalFetchParams = Reflect.get(target, prop, receiver);
|
|
1371
|
+
const isInternal = Reflect.get(target, "isInternalExecution", receiver) === true;
|
|
1482
1372
|
if (typeof originalFetchParams === "function") {
|
|
1483
1373
|
return function(...args) {
|
|
1484
1374
|
const originalReturnValue = originalFetchParams.apply(this, args);
|
|
@@ -1504,7 +1394,8 @@ function createAbortableDecorator(command, options) {
|
|
|
1504
1394
|
}
|
|
1505
1395
|
return Reflect.has(target, prop);
|
|
1506
1396
|
}
|
|
1507
|
-
}
|
|
1397
|
+
};
|
|
1398
|
+
return new Proxy(command, handler);
|
|
1508
1399
|
} catch (error) {
|
|
1509
1400
|
if (process.env.NODE_ENV !== "production") {
|
|
1510
1401
|
console.error(
|
|
@@ -2644,7 +2535,7 @@ function buildServiceDescriptor$d(luvio) {
|
|
|
2644
2535
|
},
|
|
2645
2536
|
};
|
|
2646
2537
|
}
|
|
2647
|
-
// version: 1.
|
|
2538
|
+
// version: 1.445.0-117c9de71a
|
|
2648
2539
|
|
|
2649
2540
|
class AuraGraphQLNormalizedCacheControlCommand extends AuraNormalizedCacheControlCommand {
|
|
2650
2541
|
constructor(config, documentRootType, services) {
|
|
@@ -2982,7 +2873,7 @@ function buildServiceDescriptor$9(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
2982
2873
|
},
|
|
2983
2874
|
};
|
|
2984
2875
|
}
|
|
2985
|
-
// version: 1.
|
|
2876
|
+
// version: 1.445.0-117c9de71a
|
|
2986
2877
|
|
|
2987
2878
|
class RetryService {
|
|
2988
2879
|
constructor(defaultRetryPolicy) {
|
|
@@ -3408,7 +3299,10 @@ class GraphQLImperativeBindingsService {
|
|
|
3408
3299
|
const options = {
|
|
3409
3300
|
acceptedOperations: ["query"]
|
|
3410
3301
|
};
|
|
3411
|
-
const result = resolveAndValidateGraphQLConfig(
|
|
3302
|
+
const result = resolveAndValidateGraphQLConfig(
|
|
3303
|
+
params[0],
|
|
3304
|
+
options
|
|
3305
|
+
);
|
|
3412
3306
|
if (result?.isErr()) {
|
|
3413
3307
|
return result.error;
|
|
3414
3308
|
}
|
|
@@ -3605,7 +3499,10 @@ class GraphQLMutationBindingsService {
|
|
|
3605
3499
|
const options = {
|
|
3606
3500
|
acceptedOperations: ["mutation"]
|
|
3607
3501
|
};
|
|
3608
|
-
const result2 = resolveAndValidateGraphQLConfig(
|
|
3502
|
+
const result2 = resolveAndValidateGraphQLConfig(
|
|
3503
|
+
params[0],
|
|
3504
|
+
options
|
|
3505
|
+
);
|
|
3609
3506
|
if (result2?.isErr()) {
|
|
3610
3507
|
return {
|
|
3611
3508
|
data: void 0,
|
|
@@ -4667,7 +4564,7 @@ var TypeCheckShapes;
|
|
|
4667
4564
|
TypeCheckShapes[TypeCheckShapes["Integer"] = 3] = "Integer";
|
|
4668
4565
|
TypeCheckShapes[TypeCheckShapes["Unsupported"] = 4] = "Unsupported";
|
|
4669
4566
|
})(TypeCheckShapes || (TypeCheckShapes = {}));
|
|
4670
|
-
// engine version: 0.
|
|
4567
|
+
// engine version: 0.161.0-fe06f180
|
|
4671
4568
|
|
|
4672
4569
|
const { keys: keys$1 } = Object;
|
|
4673
4570
|
|
|
@@ -4762,6 +4659,10 @@ const SALESFORCE_API_BASE_URI_FLAG = 'api.salesforce.com';
|
|
|
4762
4659
|
const X_REQUEST_ID_HEADER = 'x-request-id';
|
|
4763
4660
|
const SFAPController = 'SalesforceApiPlatformController';
|
|
4764
4661
|
const SFAPJwtMethod = 'getSFAPLightningJwtService';
|
|
4662
|
+
// Parameterized mint: the POST signature's auto-generated Aura method
|
|
4663
|
+
// (`@ConnectSignature(..., generateAuraMethod = true)` on the SFAP Lightning JWT
|
|
4664
|
+
// Service Connect resource). Takes a single `requestBody` named param.
|
|
4665
|
+
const SFAPJwtPostMethod = 'postSFAPLightningJwtService';
|
|
4765
4666
|
/**
|
|
4766
4667
|
* We expect jwt info and baseUri to be present in the response.
|
|
4767
4668
|
*
|
|
@@ -4908,6 +4809,151 @@ function generateRequestId$1() {
|
|
|
4908
4809
|
}
|
|
4909
4810
|
}
|
|
4910
4811
|
|
|
4812
|
+
/**
|
|
4813
|
+
* Normalize SFAP-shaped params into the opaque `JwtMintParams` bag that callers
|
|
4814
|
+
* hand to `JwtManager.getJwt(params)`. Scopes are sorted because they are
|
|
4815
|
+
* semantically a set — without this, `['a', 'b']` and `['b', 'a']` would cache
|
|
4816
|
+
* as separate entries (OneStore treats arrays as ordered under stable-JSON
|
|
4817
|
+
* serialization; see ADR "JWT Parameterization" §2).
|
|
4818
|
+
*
|
|
4819
|
+
* MANDATORY CONSUMER ENTRY POINT. Every consumer that mints a parameterized
|
|
4820
|
+
* SFAP JWT MUST assemble its params through this function before calling the
|
|
4821
|
+
* manager. The cache key is derived by `JwtManager` from the caller's params
|
|
4822
|
+
* (`cacheKeyFor(params)`) *before* the resolver runs — so the resolver cannot
|
|
4823
|
+
* normalize after the fact. Set-stable caching therefore depends on the caller
|
|
4824
|
+
* routing params through here. Do NOT sort inside the resolver: that would only
|
|
4825
|
+
* reorder the wire body, not the cache key, and mutating the caller's params
|
|
4826
|
+
* mid-call would desync the in-flight-dedup key from the stored-token key.
|
|
4827
|
+
*/
|
|
4828
|
+
/**
|
|
4829
|
+
* Validate and narrow an opaque `JwtMintParams` bag to the SFAP-shaped subset the
|
|
4830
|
+
* resolver forwards. Returns `{ error }` (surfaced as a resolver rejection) for a
|
|
4831
|
+
* malformed bag rather than throwing.
|
|
4832
|
+
*/
|
|
4833
|
+
function coerceToSfapParams(params) {
|
|
4834
|
+
const scopes = params.scopes;
|
|
4835
|
+
const dynamicParams = params.dynamicParams;
|
|
4836
|
+
if (scopes !== undefined && !isStringArray(scopes)) {
|
|
4837
|
+
return { error: 'SFAP JWT params.scopes must be a string[] when provided.' };
|
|
4838
|
+
}
|
|
4839
|
+
if (dynamicParams !== undefined && !isPrimitiveRecord(dynamicParams)) {
|
|
4840
|
+
return {
|
|
4841
|
+
error: 'SFAP JWT params.dynamicParams must be a Record<string, string | boolean | number> when provided.',
|
|
4842
|
+
};
|
|
4843
|
+
}
|
|
4844
|
+
return { params: { scopes, dynamicParams } };
|
|
4845
|
+
}
|
|
4846
|
+
function isStringArray(value) {
|
|
4847
|
+
return Array.isArray(value) && value.every((s) => typeof s === 'string');
|
|
4848
|
+
}
|
|
4849
|
+
/**
|
|
4850
|
+
* A record whose values are JSON primitives (string, boolean, or number) — the
|
|
4851
|
+
* value types the SFAP Lightning JWT Service accepts for a dynamic parameter
|
|
4852
|
+
* (see {@link SfapDynamicParamValue}). Booleans/numbers are forwarded natively
|
|
4853
|
+
* (not stringified) so claim handlers that gate on a native `Boolean` see the
|
|
4854
|
+
* intended value. Nested objects/arrays, `null`, and `undefined` are rejected.
|
|
4855
|
+
*/
|
|
4856
|
+
function isPrimitiveRecord(value) {
|
|
4857
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
4858
|
+
return false;
|
|
4859
|
+
}
|
|
4860
|
+
return Object.values(value).every((v) => typeof v === 'string' || typeof v === 'boolean' || typeof v === 'number');
|
|
4861
|
+
}
|
|
4862
|
+
/**
|
|
4863
|
+
* Build the SFAP mint request body from the coerced params: `scopes` joined into a
|
|
4864
|
+
* single space-delimited string, `dynamicParams` mapped to `dynamicParameters.items`.
|
|
4865
|
+
* Empty scopes / dynamic params are omitted.
|
|
4866
|
+
*/
|
|
4867
|
+
function buildRequestBody(params) {
|
|
4868
|
+
const body = {};
|
|
4869
|
+
if (params.scopes && params.scopes.length > 0) {
|
|
4870
|
+
body.scopes = params.scopes.join(' ');
|
|
4871
|
+
}
|
|
4872
|
+
if (params.dynamicParams) {
|
|
4873
|
+
const items = Object.entries(params.dynamicParams).map(([name, value]) => ({ name, value }));
|
|
4874
|
+
if (items.length > 0) {
|
|
4875
|
+
body.dynamicParameters = { items };
|
|
4876
|
+
}
|
|
4877
|
+
}
|
|
4878
|
+
return body;
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4881
|
+
/**
|
|
4882
|
+
* Parameterized SFAP JWT resolver that mints over **Aura transport** instead of a
|
|
4883
|
+
* direct HTTP `fetch`.
|
|
4884
|
+
*
|
|
4885
|
+
* It dispatches the SFAP Lightning JWT Service's parameterized POST via its
|
|
4886
|
+
* auto-generated Aura controller method
|
|
4887
|
+
* `SalesforceApiPlatformController.postSFAPLightningJwtService` (generated by
|
|
4888
|
+
* `@ConnectSignature(..., generateAuraMethod = true)` on the Connect resource).
|
|
4889
|
+
* The mint inputs ride as the single `requestBody` named param, in the same
|
|
4890
|
+
* `{ scopes, dynamicParameters: { items } }` shape the HTTP resolver POSTs — built
|
|
4891
|
+
* by the shared {@link buildRequestBody}, so the two transports stay in lockstep.
|
|
4892
|
+
*
|
|
4893
|
+
* Why Aura (not the HTTP resolver): the mint endpoint is a same-origin core
|
|
4894
|
+
* resource, and routing it over Aura keeps session/CSRF handling inside the Aura
|
|
4895
|
+
* stack rather than issuing a credentialed cross-cutting `fetch` from the client.
|
|
4896
|
+
* This mirrors the legacy parameterless `platformSfapJwtResolver` in
|
|
4897
|
+
* `network-sfap.ts`, which already mints over Aura via the `getSFAPLightningJwtService`
|
|
4898
|
+
* generated method — this is the parameterized sibling of that call.
|
|
4899
|
+
*
|
|
4900
|
+
* A `JwtResolver` is invoked directly by `JwtManager` (not through Luvio's
|
|
4901
|
+
* `appRouter`/`ResourceRequest` pipeline), so the correct mechanism is a direct
|
|
4902
|
+
* named-controller `dispatchAuraAction`, not the `auraNetworkAdapter`/connect-route
|
|
4903
|
+
* table. The SFAP JWT endpoint is not registered as a connect-over-Aura route, and
|
|
4904
|
+
* a resolver has no `ResourceRequest` for the router to look up.
|
|
4905
|
+
*/
|
|
4906
|
+
class ParameterizedSfapJwtAuraResolver {
|
|
4907
|
+
getJwt(params) {
|
|
4908
|
+
return new Promise((resolve, reject) => {
|
|
4909
|
+
if (params === undefined) {
|
|
4910
|
+
// Misuse: the dispatching resolver routes parameterless calls to the
|
|
4911
|
+
// legacy resolver. Reject so production fails loudly here.
|
|
4912
|
+
reject('ParameterizedSfapJwtAuraResolver requires JwtMintParams. The legacy parameterless path should be served by platformSfapJwtResolver.');
|
|
4913
|
+
return;
|
|
4914
|
+
}
|
|
4915
|
+
const coerced = coerceToSfapParams(params);
|
|
4916
|
+
if ('error' in coerced) {
|
|
4917
|
+
reject(coerced.error);
|
|
4918
|
+
return;
|
|
4919
|
+
}
|
|
4920
|
+
// The mint inputs become the single `requestBody` named param of the
|
|
4921
|
+
// generated Aura method (Aura binds top-level keys to the controller
|
|
4922
|
+
// method's named args). Reuses the HTTP resolver's body builder so both
|
|
4923
|
+
// transports send an identical shape.
|
|
4924
|
+
const requestBody = buildRequestBody(coerced.params);
|
|
4925
|
+
// No fetchImpl / requestInterceptor / CSRF / credentials handling here —
|
|
4926
|
+
// the Aura stack owns session + CSRF. Matches the legacy resolver's call.
|
|
4927
|
+
dispatchAuraAction(`${SFAPController}.${SFAPJwtPostMethod}`, { requestBody }, defaultActionConfig)
|
|
4928
|
+
.then((response) => {
|
|
4929
|
+
const body = response.body;
|
|
4930
|
+
if (!body || typeof body.jwt !== 'string' || typeof body.baseUri !== 'string') {
|
|
4931
|
+
// Never serialize the body into the error — it may carry a JWT.
|
|
4932
|
+
reject('SFAP JWT response missing required fields (jwt, baseUri)');
|
|
4933
|
+
return;
|
|
4934
|
+
}
|
|
4935
|
+
resolve({ jwt: body.jwt, extraInfo: { baseUri: body.baseUri } });
|
|
4936
|
+
})
|
|
4937
|
+
.catch((error) => {
|
|
4938
|
+
// Error mapping ported from the legacy platformSfapJwtResolver
|
|
4939
|
+
// (network-sfap.ts): plain Errors carry a message; non-500
|
|
4940
|
+
// AuraFetchResponses are ConnectInJava errors with a typed body;
|
|
4941
|
+
// 500s carry an { error } body.
|
|
4942
|
+
if (error instanceof Error) {
|
|
4943
|
+
reject(error.message);
|
|
4944
|
+
return;
|
|
4945
|
+
}
|
|
4946
|
+
const { status } = error;
|
|
4947
|
+
if (status !== HttpStatusCode$2.ServerError) {
|
|
4948
|
+
reject(error.body.message);
|
|
4949
|
+
return;
|
|
4950
|
+
}
|
|
4951
|
+
reject(error.body.error);
|
|
4952
|
+
});
|
|
4953
|
+
});
|
|
4954
|
+
}
|
|
4955
|
+
}
|
|
4956
|
+
|
|
4911
4957
|
/**
|
|
4912
4958
|
* Observability / Critical Availability Program (230+)
|
|
4913
4959
|
*
|
|
@@ -5658,7 +5704,9 @@ class PrioritizedConfigService {
|
|
|
5658
5704
|
// ConfigService.set
|
|
5659
5705
|
set(priority, setter) {
|
|
5660
5706
|
this.validated = false;
|
|
5661
|
-
return setter(
|
|
5707
|
+
return setter(
|
|
5708
|
+
this.prioritizedConfigData[priority]
|
|
5709
|
+
);
|
|
5662
5710
|
}
|
|
5663
5711
|
// returns the highest priority value for a given path, undefined if no value
|
|
5664
5712
|
// is defined for the path at any priority
|
|
@@ -5717,25 +5765,62 @@ function getEnvironmentSetting(name) {
|
|
|
5717
5765
|
}
|
|
5718
5766
|
return undefined;
|
|
5719
5767
|
}
|
|
5720
|
-
// version: 1.
|
|
5768
|
+
// version: 1.445.0-6d38a08808
|
|
5721
5769
|
|
|
5722
5770
|
/**
|
|
5723
5771
|
* Helpers for reaching the Aura framework from the LDS Aura runtime.
|
|
5724
5772
|
*
|
|
5725
|
-
* `window.$A` is only present when the runtime is hosted inside LEX
|
|
5726
|
-
* and non-Aura runtimes it is absent.
|
|
5727
|
-
* `$A`
|
|
5728
|
-
*
|
|
5773
|
+
* `window.$A` is only present when the runtime is hosted inside Aura (LEX or
|
|
5774
|
+
* an Aura site); in tests and non-Aura runtimes it is absent. `getAura()`
|
|
5775
|
+
* centralizes the guarded lookup so the `$A` access lives in one place instead
|
|
5776
|
+
* of being duplicated across modules.
|
|
5729
5777
|
*/
|
|
5778
|
+
/**
|
|
5779
|
+
* Returns the Aura framework global (`window.$A`) when running inside Aura
|
|
5780
|
+
* (LEX or an Aura site), or `undefined` in tests and non-Aura runtimes.
|
|
5781
|
+
* Centralizes the guarded `$A` lookup so callers reach for it once and read
|
|
5782
|
+
* intent instead of repeating `typeof window` / `$A` guards.
|
|
5783
|
+
*/
|
|
5784
|
+
function getAura() {
|
|
5785
|
+
if (typeof window === 'undefined') {
|
|
5786
|
+
return undefined;
|
|
5787
|
+
}
|
|
5788
|
+
return window.$A;
|
|
5789
|
+
}
|
|
5790
|
+
/**
|
|
5791
|
+
* Fires an Aura application-level event (e.g. `aura:invalidSession`). Thin
|
|
5792
|
+
* pass-through to the `aura` framework module so callers depend on this util
|
|
5793
|
+
* rather than importing `aura` directly.
|
|
5794
|
+
*/
|
|
5795
|
+
function dispatchGlobalEvent(...args) {
|
|
5796
|
+
dispatchGlobalEvent$1(...args);
|
|
5797
|
+
}
|
|
5730
5798
|
/**
|
|
5731
5799
|
* Returns `$A.clientService` when running inside an Aura environment, or
|
|
5732
5800
|
* `undefined` otherwise. Defensive: never throws.
|
|
5733
5801
|
*/
|
|
5734
5802
|
function getAuraClientService() {
|
|
5735
|
-
|
|
5736
|
-
|
|
5803
|
+
return getAura()?.clientService;
|
|
5804
|
+
}
|
|
5805
|
+
/**
|
|
5806
|
+
* Returns `true` when the Aura runtime is hosted inside an Aura/Experience
|
|
5807
|
+
* site (Experience Builder / `communityApp`) rather than LEX (one.app).
|
|
5808
|
+
* `$A.get('$Site')` is present and truthy on Aura sites and absent/falsy in
|
|
5809
|
+
* LEX. A stable per-page signal, so it is safe to evaluate once at module
|
|
5810
|
+
* load. Defensive: never throws.
|
|
5811
|
+
*
|
|
5812
|
+
* Used to keep the OneStore GraphQL adapter — and the HTTP UIAPI fetch path —
|
|
5813
|
+
* on the Aura transport for sites, because the HTTP transport's CSRF handling
|
|
5814
|
+
* does not work in the Aura Sites runtime (W-23092947).
|
|
5815
|
+
*/
|
|
5816
|
+
function isAuraSite() {
|
|
5817
|
+
const aura = getAura();
|
|
5818
|
+
try {
|
|
5819
|
+
return !!aura?.get?.('$Site');
|
|
5820
|
+
}
|
|
5821
|
+
catch {
|
|
5822
|
+
return false;
|
|
5737
5823
|
}
|
|
5738
|
-
return window.$A.clientService;
|
|
5739
5824
|
}
|
|
5740
5825
|
|
|
5741
5826
|
const auraClientService = getAuraClientService();
|
|
@@ -5997,34 +6082,54 @@ function buildLuvioPageScopedCacheRequestInterceptor() {
|
|
|
5997
6082
|
};
|
|
5998
6083
|
}
|
|
5999
6084
|
|
|
6000
|
-
|
|
6085
|
+
// Two distinct session-expiration cases on the LEX runtime path:
|
|
6086
|
+
// - 401 + INVALID_SESSION_ID — auth token rejected
|
|
6087
|
+
// - 403 + `x-sfdc-csrf-failure: true` — CSRF token rejected, session is dead
|
|
6088
|
+
// Both fire `aura:invalidSession`, which routes the user back to login.
|
|
6089
|
+
//
|
|
6090
|
+
// 403 access denials (INSUFFICIENT_ACCESS / INSUFFICIENT_ACCESS_OR_READONLY) are
|
|
6091
|
+
// intentionally NOT handled here — `aura:noAccess` without a `redirectURL`
|
|
6092
|
+
// triggers AuraClientService.hardRefresh() which is too heavy-handed for routine
|
|
6093
|
+
// "feature not enabled for this org" responses. The wire layer surfaces those
|
|
6094
|
+
// as normal errors; onestore PR #838 (`aura-network-command`) handles the
|
|
6095
|
+
// gack-noise on the Aura action path.
|
|
6096
|
+
function isSessionExpired(status, headers, body) {
|
|
6097
|
+
if (status === 403) {
|
|
6098
|
+
return headers && headers['x-sfdc-csrf-failure'] === 'true';
|
|
6099
|
+
}
|
|
6100
|
+
if (status === 401) {
|
|
6101
|
+
// Connect REST returns errors as `[{ errorCode, ... }, ...]`; Aura Shape A
|
|
6102
|
+
// uses `{ errorCode, ... }`. This interceptor runs before
|
|
6103
|
+
// `buildLuvioErrorBodyNormalizationInterceptor`, so handle both.
|
|
6104
|
+
const errorCode = Array.isArray(body)
|
|
6105
|
+
? body[0] && body[0].errorCode
|
|
6106
|
+
: body && body.errorCode;
|
|
6107
|
+
return errorCode === 'INVALID_SESSION_ID';
|
|
6108
|
+
}
|
|
6109
|
+
return false;
|
|
6110
|
+
}
|
|
6111
|
+
function buildLexRuntimeSessionExpirationResponseInterceptor(logger) {
|
|
6001
6112
|
return async (response) => {
|
|
6002
|
-
|
|
6003
|
-
|
|
6004
|
-
|
|
6005
|
-
|
|
6006
|
-
|
|
6007
|
-
|
|
6008
|
-
|
|
6009
|
-
|
|
6010
|
-
}, 0);
|
|
6011
|
-
}
|
|
6012
|
-
}
|
|
6013
|
-
catch (error) {
|
|
6014
|
-
logger.warn(`Error parsing response from LEX runtime service: ${error}`);
|
|
6113
|
+
const { status } = response;
|
|
6114
|
+
if (status !== 401 && status !== 403)
|
|
6115
|
+
return response;
|
|
6116
|
+
try {
|
|
6117
|
+
const coerced = (await coerceResponseToFetchResponse(response.clone()));
|
|
6118
|
+
if (isSessionExpired(status, coerced.headers, coerced.body)) {
|
|
6119
|
+
logger.warn(`Received ${status} status code from LEX runtime service`);
|
|
6120
|
+
window.setTimeout(() => dispatchGlobalEvent('aura:invalidSession'), 0);
|
|
6015
6121
|
}
|
|
6016
6122
|
}
|
|
6123
|
+
catch (error) {
|
|
6124
|
+
logger.warn(`Error parsing response from LEX runtime service: ${error}`);
|
|
6125
|
+
}
|
|
6017
6126
|
return response;
|
|
6018
6127
|
};
|
|
6019
6128
|
}
|
|
6020
|
-
function
|
|
6129
|
+
function buildLexRuntimeLuvioSessionExpirationResponseInterceptor() {
|
|
6021
6130
|
return async (response) => {
|
|
6022
|
-
if (response.status
|
|
6023
|
-
|
|
6024
|
-
window.setTimeout(() => {
|
|
6025
|
-
dispatchGlobalEvent('aura:invalidSession');
|
|
6026
|
-
}, 0);
|
|
6027
|
-
}
|
|
6131
|
+
if (isSessionExpired(response.status, response.headers, response.body)) {
|
|
6132
|
+
window.setTimeout(() => dispatchGlobalEvent('aura:invalidSession'), 0);
|
|
6028
6133
|
}
|
|
6029
6134
|
return response;
|
|
6030
6135
|
};
|
|
@@ -7134,6 +7239,13 @@ const PREDICATE_PATH_SETS = [
|
|
|
7134
7239
|
},
|
|
7135
7240
|
];
|
|
7136
7241
|
function getEnabledPaths() {
|
|
7242
|
+
// On Aura/Experience sites the HTTP UIAPI transport's CSRF handling is
|
|
7243
|
+
// broken (W-23092947), so disable every HTTP UIAPI path here and let LDS
|
|
7244
|
+
// fall back to the Aura transport. LEX (one.app / OneRuntime) is
|
|
7245
|
+
// unaffected. This guards all current and future predicates in one place.
|
|
7246
|
+
if (isAuraSite()) {
|
|
7247
|
+
return [];
|
|
7248
|
+
}
|
|
7137
7249
|
const enabled = new Set();
|
|
7138
7250
|
for (const { predicate, paths } of PREDICATE_PATH_SETS) {
|
|
7139
7251
|
if (predicate()) {
|
|
@@ -7203,7 +7315,7 @@ const composedFetchNetworkAdapter = {
|
|
|
7203
7315
|
retry: buildLuvioFetchRetryInterceptor(),
|
|
7204
7316
|
response: [
|
|
7205
7317
|
buildLexRuntimeLuvio5xxStatusResponseInterceptor(),
|
|
7206
|
-
|
|
7318
|
+
buildLexRuntimeLuvioSessionExpirationResponseInterceptor(),
|
|
7207
7319
|
buildLuvioErrorBodyNormalizationInterceptor(),
|
|
7208
7320
|
buildLuvioTransportMarksReceiveInterceptor(),
|
|
7209
7321
|
buildLuvioActionMarksReceiveInterceptor(),
|
|
@@ -7369,9 +7481,106 @@ function buildCsrfRetryInterceptor() {
|
|
|
7369
7481
|
};
|
|
7370
7482
|
}
|
|
7371
7483
|
|
|
7484
|
+
/**
|
|
7485
|
+
* The context-seed key under which a custom command forwards its JWT mint
|
|
7486
|
+
* parameters. The framework's `buildServiceDescriptor` merges the request init's
|
|
7487
|
+
* `__contextSeed` onto the per-request interceptor context, so this interceptor
|
|
7488
|
+
* reads the params off `context[JWT_MINT_PARAMS_SEED_KEY]`.
|
|
7489
|
+
*
|
|
7490
|
+
* This is a cross-team contract: the custom command writes this key, this
|
|
7491
|
+
* interceptor reads it. It is intentionally an opaque key — OneStore does not
|
|
7492
|
+
* define it and never inspects the param shape; the typed shape lives in the
|
|
7493
|
+
* resolver.
|
|
7494
|
+
*/
|
|
7495
|
+
const JWT_MINT_PARAMS_SEED_KEY = 'jwtMintParams';
|
|
7496
|
+
/**
|
|
7497
|
+
* Returns `true` if the fetch arguments already carry an `Authorization` header,
|
|
7498
|
+
* across the three shapes the framework's `setHeader` handles: a `Request`
|
|
7499
|
+
* resource's own headers, an `options.headers` `Headers` instance, or a plain
|
|
7500
|
+
* record. The descriptor's guarded legacy interceptor uses this to skip when the
|
|
7501
|
+
* parameterized interceptor has already authorized the request — avoiding a second
|
|
7502
|
+
* mint and the throw `setHeaderAuthorization` raises on an existing header.
|
|
7503
|
+
*/
|
|
7504
|
+
function hasAuthorizationHeader([resource, options]) {
|
|
7505
|
+
if (resource instanceof Request && resource.headers.has('Authorization')) {
|
|
7506
|
+
return true;
|
|
7507
|
+
}
|
|
7508
|
+
const headers = options?.headers;
|
|
7509
|
+
if (headers === undefined) {
|
|
7510
|
+
return false;
|
|
7511
|
+
}
|
|
7512
|
+
if (headers instanceof Headers) {
|
|
7513
|
+
return headers.has('Authorization');
|
|
7514
|
+
}
|
|
7515
|
+
if (Array.isArray(headers)) {
|
|
7516
|
+
return headers.some(([name]) => name.toLowerCase() === 'authorization');
|
|
7517
|
+
}
|
|
7518
|
+
return Reflect.has(headers, 'Authorization');
|
|
7519
|
+
}
|
|
7520
|
+
/**
|
|
7521
|
+
* Builds the request interceptor that bridges the per-request context seed to the
|
|
7522
|
+
* dispatching SFAP JwtManager for the **parameterized** mint path.
|
|
7523
|
+
*
|
|
7524
|
+
* For a parameterized SFAP command, the context carries `jwtMintParams`. This
|
|
7525
|
+
* interceptor reads them, calls `jwtManager.getJwt(params)` (which the dispatching
|
|
7526
|
+
* resolver routes to the parameterized resolver), attaches the `Authorization`
|
|
7527
|
+
* header, and rewrites the request URL via the minted `baseUri`. The presence of
|
|
7528
|
+
* that `Authorization` header is the signal the descriptor's guarded legacy
|
|
7529
|
+
* interceptor uses to skip — so the legacy path does not mint a second time.
|
|
7530
|
+
*
|
|
7531
|
+
* For a legacy parameterless command the context carries no `jwtMintParams`, so
|
|
7532
|
+
* this interceptor **early-returns on its first line** and the request flows
|
|
7533
|
+
* unchanged to the legacy `buildJwtRequestHeaderInterceptor` — guaranteeing zero
|
|
7534
|
+
* behavior change for non-opted-in adapters.
|
|
7535
|
+
*
|
|
7536
|
+
* Lives in `lds-lightning-platform` (not OneStore) beside the existing SFAP/CSRF
|
|
7537
|
+
* interceptors, per the JWT-parameterization ADR §5: OneStore provides only the
|
|
7538
|
+
* generic interceptor mechanism and the opaque context-seed channel; the service-
|
|
7539
|
+
* specific bridge is a runtime-layer concern.
|
|
7540
|
+
*
|
|
7541
|
+
* @param jwtManager - the dispatching SFAP JwtManager
|
|
7542
|
+
* @param jwtRequestModifier - applies the minted `extraInfo.baseUri` to the request URL
|
|
7543
|
+
*/
|
|
7544
|
+
function buildJwtParameterizationInterceptor(jwtManager, jwtRequestModifier = (_extraInfo, fetchArgs) => fetchArgs) {
|
|
7545
|
+
return (fetchArgs, context) => {
|
|
7546
|
+
const jwtContext = context;
|
|
7547
|
+
const mintParams = jwtContext?.[JWT_MINT_PARAMS_SEED_KEY];
|
|
7548
|
+
// No mint params → not a parameterized request. Do nothing; the legacy
|
|
7549
|
+
// interceptor handles it. This MUST be the first statement so non-opted-in
|
|
7550
|
+
// SFAP commands observe no work at all.
|
|
7551
|
+
if (mintParams === undefined) {
|
|
7552
|
+
return resolvedPromiseLike$2(fetchArgs);
|
|
7553
|
+
}
|
|
7554
|
+
return resolvedPromiseLike$2(jwtManager.getJwt(mintParams)).then((token) => {
|
|
7555
|
+
const fetchArgsWithAuthorization = setHeaderAuthorization(token, fetchArgs);
|
|
7556
|
+
return token.extraInfo
|
|
7557
|
+
? jwtRequestModifier(token.extraInfo, fetchArgsWithAuthorization)
|
|
7558
|
+
: fetchArgsWithAuthorization;
|
|
7559
|
+
});
|
|
7560
|
+
};
|
|
7561
|
+
}
|
|
7562
|
+
|
|
7372
7563
|
const SFAP_BASE_URL = 'api.salesforce.com';
|
|
7564
|
+
function buildDispatchingSfapJwtResolver(legacyResolver, parameterizedResolver) {
|
|
7565
|
+
return {
|
|
7566
|
+
getJwt(params) {
|
|
7567
|
+
if (params === undefined) {
|
|
7568
|
+
return legacyResolver.getJwt();
|
|
7569
|
+
}
|
|
7570
|
+
return parameterizedResolver.getJwt(params);
|
|
7571
|
+
},
|
|
7572
|
+
};
|
|
7573
|
+
}
|
|
7574
|
+
// The parameterized mint is dispatched over **Aura transport**:
|
|
7575
|
+
// the resolver calls the SFAP Lightning JWT Service's auto-generated Aura method
|
|
7576
|
+
// `SalesforceApiPlatformController.postSFAPLightningJwtService`, so session + CSRF
|
|
7577
|
+
// are handled inside the Aura stack. This mirrors the legacy parameterless
|
|
7578
|
+
// `platformSfapJwtResolver`, which already mints over Aura. The minted JWT is then
|
|
7579
|
+
// attached as a Bearer token on the downstream SFAP API request (which stays HTTP).
|
|
7580
|
+
const parameterizedSfapJwtResolver = new ParameterizedSfapJwtAuraResolver();
|
|
7581
|
+
const sfapJwtResolver = buildDispatchingSfapJwtResolver(platformSfapJwtResolver, parameterizedSfapJwtResolver);
|
|
7373
7582
|
const sfapJwtRepository = new JwtRepository();
|
|
7374
|
-
const sfapJwtManager = new JwtManager(sfapJwtRepository,
|
|
7583
|
+
const sfapJwtManager = new JwtManager(sfapJwtRepository, sfapJwtResolver);
|
|
7375
7584
|
function prefetchSfapJwt() {
|
|
7376
7585
|
const maybePromise = sfapJwtManager.getJwt();
|
|
7377
7586
|
if ('then' in maybePromise) {
|
|
@@ -7382,8 +7591,12 @@ function prefetchSfapJwt() {
|
|
|
7382
7591
|
function buildJwtAuthorizedSfapFetchServiceDescriptor(logger) {
|
|
7383
7592
|
const jwtAuthorizedFetchService = buildServiceDescriptor$2({
|
|
7384
7593
|
createContext: createInstrumentationIdContext(),
|
|
7385
|
-
request: [
|
|
7386
|
-
|
|
7594
|
+
request: [
|
|
7595
|
+
buildThirdPartyTrackerRegisterInterceptor(),
|
|
7596
|
+
buildJwtParameterizationInterceptor(sfapJwtManager, buildSfapJwtRequestModifier(logger)),
|
|
7597
|
+
// Guarded so it is skipped once the parameterized interceptor handled the request.
|
|
7598
|
+
buildGuardedLegacyJwtRequestInterceptor(logger),
|
|
7599
|
+
],
|
|
7387
7600
|
finally: [buildThirdPartyTrackerFinishInterceptor()],
|
|
7388
7601
|
});
|
|
7389
7602
|
return {
|
|
@@ -7463,8 +7676,13 @@ function buildUnauthorizedFetchServiceDescriptor() {
|
|
|
7463
7676
|
tags: { authenticationScopes: '' },
|
|
7464
7677
|
};
|
|
7465
7678
|
}
|
|
7466
|
-
|
|
7467
|
-
|
|
7679
|
+
/**
|
|
7680
|
+
* The `JwtRequestModifier` shared by both the legacy and parameterized SFAP
|
|
7681
|
+
* interceptors: it rewrites the request URL's host/protocol to the minted
|
|
7682
|
+
* `extraInfo.baseUri` (only for `api.salesforce.com` resources).
|
|
7683
|
+
*/
|
|
7684
|
+
function buildSfapJwtRequestModifier(logger) {
|
|
7685
|
+
return ({ baseUri }, [resource, request]) => {
|
|
7468
7686
|
if (typeof resource !== 'string' && !(resource instanceof URL)) {
|
|
7469
7687
|
// istanbul ignore else: this will not be tested in NODE_ENV = production for test coverage
|
|
7470
7688
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -7482,8 +7700,22 @@ function buildJwtRequestInterceptor(logger) {
|
|
|
7482
7700
|
url.protocol = overrideUrl.protocol;
|
|
7483
7701
|
return [url, request];
|
|
7484
7702
|
};
|
|
7485
|
-
|
|
7486
|
-
|
|
7703
|
+
}
|
|
7704
|
+
function buildJwtRequestInterceptor(logger) {
|
|
7705
|
+
return buildJwtRequestHeaderInterceptor(sfapJwtManager, buildSfapJwtRequestModifier(logger));
|
|
7706
|
+
}
|
|
7707
|
+
/**
|
|
7708
|
+
* Wraps the legacy `buildJwtRequestHeaderInterceptor` with a pass-through guard:
|
|
7709
|
+
* when the parameterized interceptor has already authorized the request (an
|
|
7710
|
+
* `Authorization` header is present), this returns `args` untouched so the legacy
|
|
7711
|
+
* interceptor does not mint a second time or attempt to set a duplicate
|
|
7712
|
+
* Authorization header (which `setHeaderAuthorization` throws on). For every legacy
|
|
7713
|
+
* (non-parameterized) request no Authorization header is present yet, so the legacy
|
|
7714
|
+
* interceptor runs exactly as before — a strict pass-through.
|
|
7715
|
+
*/
|
|
7716
|
+
function buildGuardedLegacyJwtRequestInterceptor(logger) {
|
|
7717
|
+
const legacyInterceptor = buildJwtRequestInterceptor(logger);
|
|
7718
|
+
return (args) => hasAuthorizationHeader(args) ? resolvedPromiseLike$2(args) : legacyInterceptor(args);
|
|
7487
7719
|
}
|
|
7488
7720
|
|
|
7489
7721
|
const PDL_EXECUTE_ASYNC_OPTIONS = {
|
|
@@ -9650,7 +9882,9 @@ function addAllToSet(targetSet, sourceSet) {
|
|
|
9650
9882
|
}
|
|
9651
9883
|
function resolvedPromiseLike(result) {
|
|
9652
9884
|
if (isPromiseLike(result)) {
|
|
9653
|
-
return result.then(
|
|
9885
|
+
return result.then(
|
|
9886
|
+
(nextResult) => nextResult
|
|
9887
|
+
);
|
|
9654
9888
|
}
|
|
9655
9889
|
return {
|
|
9656
9890
|
then: (onFulfilled, _onRejected) => {
|
|
@@ -9667,7 +9901,9 @@ function resolvedPromiseLike(result) {
|
|
|
9667
9901
|
}
|
|
9668
9902
|
function rejectedPromiseLike(reason) {
|
|
9669
9903
|
if (isPromiseLike(reason)) {
|
|
9670
|
-
return reason.then(
|
|
9904
|
+
return reason.then(
|
|
9905
|
+
(nextResult) => nextResult
|
|
9906
|
+
);
|
|
9671
9907
|
}
|
|
9672
9908
|
return {
|
|
9673
9909
|
then: (_onFulfilled, onRejected) => {
|
|
@@ -10146,7 +10382,7 @@ function getLexRuntimeDefaultInterceptorConfig(logger) {
|
|
|
10146
10382
|
retry: buildCsrfRetryInterceptor(),
|
|
10147
10383
|
response: [
|
|
10148
10384
|
buildLexRuntime5xxStatusResponseInterceptor(logger),
|
|
10149
|
-
|
|
10385
|
+
buildLexRuntimeSessionExpirationResponseInterceptor(logger),
|
|
10150
10386
|
buildTransportMarksReceiveInterceptor(),
|
|
10151
10387
|
buildActionMarksReceiveInterceptor(),
|
|
10152
10388
|
],
|
|
@@ -10163,7 +10399,7 @@ function buildLexRuntimeAllow5xxFetchServiceDescriptor(logger, retryService) {
|
|
|
10163
10399
|
...config,
|
|
10164
10400
|
// Omit 5xx interceptor - allow 5xx responses to pass through
|
|
10165
10401
|
response: [
|
|
10166
|
-
|
|
10402
|
+
buildLexRuntimeSessionExpirationResponseInterceptor(logger),
|
|
10167
10403
|
buildTransportMarksReceiveInterceptor(),
|
|
10168
10404
|
buildActionMarksReceiveInterceptor(),
|
|
10169
10405
|
],
|
|
@@ -10998,6 +11234,11 @@ function initializeOneStore(luvio) {
|
|
|
10998
11234
|
};
|
|
10999
11235
|
// set flags based on gates
|
|
11000
11236
|
featureFlagsService.set('useOneStoreGraphQL', useOneStoreGraphql.isOpen({ fallback: false }));
|
|
11237
|
+
// On Aura/Experience sites the HTTP transport's CSRF handling is broken
|
|
11238
|
+
// (W-23092947), so signal the OneStore GraphQL command to use the Aura
|
|
11239
|
+
// transport there. HTTP remains the default in LEX. Paired with the HTTP
|
|
11240
|
+
// UIAPI fetch path being disabled on sites (see network-fetch.ts).
|
|
11241
|
+
featureFlagsService.set('graphQLUseAura', isAuraSite());
|
|
11001
11242
|
const services = [
|
|
11002
11243
|
instrumentationServiceDescriptor,
|
|
11003
11244
|
buildLexRuntimeDefaultFetchServiceDescriptor(loggerService, retryService),
|
|
@@ -11009,13 +11250,12 @@ function initializeOneStore(luvio) {
|
|
|
11009
11250
|
// Ordering of services matters - L1 only CacheControlService must come before durable
|
|
11010
11251
|
buildServiceDescriptor$g(cacheServiceDescriptor.service, inMemoryCacheInclusionPolicyServiceDescriptor.service, instrumentationServiceDescriptor.service),
|
|
11011
11252
|
durableCacheControlService,
|
|
11012
|
-
buildServiceDescriptor$
|
|
11253
|
+
buildServiceDescriptor$p(),
|
|
11013
11254
|
buildServiceDescriptor$e(),
|
|
11014
11255
|
buildServiceDescriptor$m(),
|
|
11015
|
-
buildServiceDescriptor$
|
|
11256
|
+
buildServiceDescriptor$q(),
|
|
11016
11257
|
buildServiceDescriptor$l(),
|
|
11017
11258
|
buildServiceDescriptor$k(),
|
|
11018
|
-
buildServiceDescriptor$p(),
|
|
11019
11259
|
buildServiceDescriptor$o(),
|
|
11020
11260
|
buildServiceDescriptor$n(),
|
|
11021
11261
|
buildServiceDescriptor$f(),
|
|
@@ -11058,4 +11298,4 @@ function ldsEngineCreator() {
|
|
|
11058
11298
|
}
|
|
11059
11299
|
|
|
11060
11300
|
export { LexRequestStrategy, PdlPrefetcherEventType, PdlRequestPriority, buildPredictorForContext, configService, ldsEngineCreator as default, initializeLDS, initializeOneStore, notifyUpdateAvailableFactory, registerRequestStrategy, saveRequestAsPrediction, subscribeToPrefetcherEvents, unregisterRequestStrategy, whenPredictionsReady };
|
|
11061
|
-
// version: 1.
|
|
11301
|
+
// version: 1.445.0-117c9de71a
|