@salesforce/lds-runtime-aura 1.443.0 → 1.444.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 +356 -42
- package/dist/types/aura-utils.d.ts +7 -0
- 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 +69 -0
- package/package.json +46 -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';
|
|
@@ -234,6 +234,19 @@ var HttpStatusCode$1 = /* @__PURE__ */ ((HttpStatusCode2) => {
|
|
|
234
234
|
HttpStatusCode2[HttpStatusCode2["GatewayTimeout"] = 504] = "GatewayTimeout";
|
|
235
235
|
return HttpStatusCode2;
|
|
236
236
|
})(HttpStatusCode$1 || {});
|
|
237
|
+
function getFetchResponseFromAuraError(err2) {
|
|
238
|
+
if (err2.data !== void 0 && err2.data.statusCode !== void 0) {
|
|
239
|
+
let data = {};
|
|
240
|
+
data = err2.data;
|
|
241
|
+
if (err2.id !== void 0) {
|
|
242
|
+
data.id = err2.id;
|
|
243
|
+
}
|
|
244
|
+
return new FetchResponse(data.statusCode, data);
|
|
245
|
+
}
|
|
246
|
+
return new FetchResponse(500, {
|
|
247
|
+
error: err2.message
|
|
248
|
+
});
|
|
249
|
+
}
|
|
237
250
|
async function coerceResponseToFetchResponse(response) {
|
|
238
251
|
const { status } = response;
|
|
239
252
|
const responseHeaders = {};
|
|
@@ -388,7 +401,7 @@ class AuraNetworkCommand extends NetworkCommand$1 {
|
|
|
388
401
|
);
|
|
389
402
|
}
|
|
390
403
|
coerceAuraErrors(auraErrors) {
|
|
391
|
-
return
|
|
404
|
+
return new UserVisibleError(getFetchResponseFromAuraError(auraErrors[0]));
|
|
392
405
|
}
|
|
393
406
|
/**
|
|
394
407
|
* Customize how non-2xx fetch fallback responses are converted into errors.
|
|
@@ -573,7 +586,10 @@ function deepEquals$1(x, y) {
|
|
|
573
586
|
}
|
|
574
587
|
for (let i = 0; i < xkeys.length; ++i) {
|
|
575
588
|
const key = xkeys[i];
|
|
576
|
-
if (!deepEquals$1(
|
|
589
|
+
if (!deepEquals$1(
|
|
590
|
+
x[key],
|
|
591
|
+
y[key]
|
|
592
|
+
)) {
|
|
577
593
|
return false;
|
|
578
594
|
}
|
|
579
595
|
}
|
|
@@ -2644,7 +2660,7 @@ function buildServiceDescriptor$d(luvio) {
|
|
|
2644
2660
|
},
|
|
2645
2661
|
};
|
|
2646
2662
|
}
|
|
2647
|
-
// version: 1.
|
|
2663
|
+
// version: 1.444.0-a7f42f9edf
|
|
2648
2664
|
|
|
2649
2665
|
class AuraGraphQLNormalizedCacheControlCommand extends AuraNormalizedCacheControlCommand {
|
|
2650
2666
|
constructor(config, documentRootType, services) {
|
|
@@ -2982,7 +2998,7 @@ function buildServiceDescriptor$9(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
2982
2998
|
},
|
|
2983
2999
|
};
|
|
2984
3000
|
}
|
|
2985
|
-
// version: 1.
|
|
3001
|
+
// version: 1.444.0-a7f42f9edf
|
|
2986
3002
|
|
|
2987
3003
|
class RetryService {
|
|
2988
3004
|
constructor(defaultRetryPolicy) {
|
|
@@ -3408,7 +3424,10 @@ class GraphQLImperativeBindingsService {
|
|
|
3408
3424
|
const options = {
|
|
3409
3425
|
acceptedOperations: ["query"]
|
|
3410
3426
|
};
|
|
3411
|
-
const result = resolveAndValidateGraphQLConfig(
|
|
3427
|
+
const result = resolveAndValidateGraphQLConfig(
|
|
3428
|
+
params[0],
|
|
3429
|
+
options
|
|
3430
|
+
);
|
|
3412
3431
|
if (result?.isErr()) {
|
|
3413
3432
|
return result.error;
|
|
3414
3433
|
}
|
|
@@ -3605,7 +3624,10 @@ class GraphQLMutationBindingsService {
|
|
|
3605
3624
|
const options = {
|
|
3606
3625
|
acceptedOperations: ["mutation"]
|
|
3607
3626
|
};
|
|
3608
|
-
const result2 = resolveAndValidateGraphQLConfig(
|
|
3627
|
+
const result2 = resolveAndValidateGraphQLConfig(
|
|
3628
|
+
params[0],
|
|
3629
|
+
options
|
|
3630
|
+
);
|
|
3609
3631
|
if (result2?.isErr()) {
|
|
3610
3632
|
return {
|
|
3611
3633
|
data: void 0,
|
|
@@ -4667,7 +4689,7 @@ var TypeCheckShapes;
|
|
|
4667
4689
|
TypeCheckShapes[TypeCheckShapes["Integer"] = 3] = "Integer";
|
|
4668
4690
|
TypeCheckShapes[TypeCheckShapes["Unsupported"] = 4] = "Unsupported";
|
|
4669
4691
|
})(TypeCheckShapes || (TypeCheckShapes = {}));
|
|
4670
|
-
// engine version: 0.
|
|
4692
|
+
// engine version: 0.161.0-fe06f180
|
|
4671
4693
|
|
|
4672
4694
|
const { keys: keys$1 } = Object;
|
|
4673
4695
|
|
|
@@ -4762,6 +4784,10 @@ const SALESFORCE_API_BASE_URI_FLAG = 'api.salesforce.com';
|
|
|
4762
4784
|
const X_REQUEST_ID_HEADER = 'x-request-id';
|
|
4763
4785
|
const SFAPController = 'SalesforceApiPlatformController';
|
|
4764
4786
|
const SFAPJwtMethod = 'getSFAPLightningJwtService';
|
|
4787
|
+
// Parameterized mint: the POST signature's auto-generated Aura method
|
|
4788
|
+
// (`@ConnectSignature(..., generateAuraMethod = true)` on the SFAP Lightning JWT
|
|
4789
|
+
// Service Connect resource). Takes a single `requestBody` named param.
|
|
4790
|
+
const SFAPJwtPostMethod = 'postSFAPLightningJwtService';
|
|
4765
4791
|
/**
|
|
4766
4792
|
* We expect jwt info and baseUri to be present in the response.
|
|
4767
4793
|
*
|
|
@@ -4908,6 +4934,144 @@ function generateRequestId$1() {
|
|
|
4908
4934
|
}
|
|
4909
4935
|
}
|
|
4910
4936
|
|
|
4937
|
+
/**
|
|
4938
|
+
* Normalize SFAP-shaped params into the opaque `JwtMintParams` bag that callers
|
|
4939
|
+
* hand to `JwtManager.getJwt(params)`. Scopes are sorted because they are
|
|
4940
|
+
* semantically a set — without this, `['a', 'b']` and `['b', 'a']` would cache
|
|
4941
|
+
* as separate entries (OneStore treats arrays as ordered under stable-JSON
|
|
4942
|
+
* serialization; see ADR "JWT Parameterization" §2).
|
|
4943
|
+
*
|
|
4944
|
+
* MANDATORY CONSUMER ENTRY POINT. Every consumer that mints a parameterized
|
|
4945
|
+
* SFAP JWT MUST assemble its params through this function before calling the
|
|
4946
|
+
* manager. The cache key is derived by `JwtManager` from the caller's params
|
|
4947
|
+
* (`cacheKeyFor(params)`) *before* the resolver runs — so the resolver cannot
|
|
4948
|
+
* normalize after the fact. Set-stable caching therefore depends on the caller
|
|
4949
|
+
* routing params through here. Do NOT sort inside the resolver: that would only
|
|
4950
|
+
* reorder the wire body, not the cache key, and mutating the caller's params
|
|
4951
|
+
* mid-call would desync the in-flight-dedup key from the stored-token key.
|
|
4952
|
+
*/
|
|
4953
|
+
/**
|
|
4954
|
+
* Validate and narrow an opaque `JwtMintParams` bag to the SFAP-shaped subset the
|
|
4955
|
+
* resolver forwards. Returns `{ error }` (surfaced as a resolver rejection) for a
|
|
4956
|
+
* malformed bag rather than throwing.
|
|
4957
|
+
*/
|
|
4958
|
+
function coerceToSfapParams(params) {
|
|
4959
|
+
const scopes = params.scopes;
|
|
4960
|
+
const dynamicParams = params.dynamicParams;
|
|
4961
|
+
if (scopes !== undefined && !isStringArray(scopes)) {
|
|
4962
|
+
return { error: 'SFAP JWT params.scopes must be a string[] when provided.' };
|
|
4963
|
+
}
|
|
4964
|
+
if (dynamicParams !== undefined && !isStringRecord(dynamicParams)) {
|
|
4965
|
+
return {
|
|
4966
|
+
error: 'SFAP JWT params.dynamicParams must be a Record<string, string> when provided.',
|
|
4967
|
+
};
|
|
4968
|
+
}
|
|
4969
|
+
return { params: { scopes, dynamicParams } };
|
|
4970
|
+
}
|
|
4971
|
+
function isStringArray(value) {
|
|
4972
|
+
return Array.isArray(value) && value.every((s) => typeof s === 'string');
|
|
4973
|
+
}
|
|
4974
|
+
function isStringRecord(value) {
|
|
4975
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
4976
|
+
return false;
|
|
4977
|
+
}
|
|
4978
|
+
return Object.values(value).every((v) => typeof v === 'string');
|
|
4979
|
+
}
|
|
4980
|
+
/**
|
|
4981
|
+
* Build the SFAP mint request body from the coerced params: `scopes` joined into a
|
|
4982
|
+
* single space-delimited string, `dynamicParams` mapped to `dynamicParameters.items`.
|
|
4983
|
+
* Empty scopes / dynamic params are omitted.
|
|
4984
|
+
*/
|
|
4985
|
+
function buildRequestBody(params) {
|
|
4986
|
+
const body = {};
|
|
4987
|
+
if (params.scopes && params.scopes.length > 0) {
|
|
4988
|
+
body.scopes = params.scopes.join(' ');
|
|
4989
|
+
}
|
|
4990
|
+
if (params.dynamicParams) {
|
|
4991
|
+
const items = Object.entries(params.dynamicParams).map(([name, value]) => ({ name, value }));
|
|
4992
|
+
if (items.length > 0) {
|
|
4993
|
+
body.dynamicParameters = { items };
|
|
4994
|
+
}
|
|
4995
|
+
}
|
|
4996
|
+
return body;
|
|
4997
|
+
}
|
|
4998
|
+
|
|
4999
|
+
/**
|
|
5000
|
+
* Parameterized SFAP JWT resolver that mints over **Aura transport** instead of a
|
|
5001
|
+
* direct HTTP `fetch`.
|
|
5002
|
+
*
|
|
5003
|
+
* It dispatches the SFAP Lightning JWT Service's parameterized POST via its
|
|
5004
|
+
* auto-generated Aura controller method
|
|
5005
|
+
* `SalesforceApiPlatformController.postSFAPLightningJwtService` (generated by
|
|
5006
|
+
* `@ConnectSignature(..., generateAuraMethod = true)` on the Connect resource).
|
|
5007
|
+
* The mint inputs ride as the single `requestBody` named param, in the same
|
|
5008
|
+
* `{ scopes, dynamicParameters: { items } }` shape the HTTP resolver POSTs — built
|
|
5009
|
+
* by the shared {@link buildRequestBody}, so the two transports stay in lockstep.
|
|
5010
|
+
*
|
|
5011
|
+
* Why Aura (not the HTTP resolver): the mint endpoint is a same-origin core
|
|
5012
|
+
* resource, and routing it over Aura keeps session/CSRF handling inside the Aura
|
|
5013
|
+
* stack rather than issuing a credentialed cross-cutting `fetch` from the client.
|
|
5014
|
+
* This mirrors the legacy parameterless `platformSfapJwtResolver` in
|
|
5015
|
+
* `network-sfap.ts`, which already mints over Aura via the `getSFAPLightningJwtService`
|
|
5016
|
+
* generated method — this is the parameterized sibling of that call.
|
|
5017
|
+
*
|
|
5018
|
+
* A `JwtResolver` is invoked directly by `JwtManager` (not through Luvio's
|
|
5019
|
+
* `appRouter`/`ResourceRequest` pipeline), so the correct mechanism is a direct
|
|
5020
|
+
* named-controller `dispatchAuraAction`, not the `auraNetworkAdapter`/connect-route
|
|
5021
|
+
* table. The SFAP JWT endpoint is not registered as a connect-over-Aura route, and
|
|
5022
|
+
* a resolver has no `ResourceRequest` for the router to look up.
|
|
5023
|
+
*/
|
|
5024
|
+
class ParameterizedSfapJwtAuraResolver {
|
|
5025
|
+
getJwt(params) {
|
|
5026
|
+
return new Promise((resolve, reject) => {
|
|
5027
|
+
if (params === undefined) {
|
|
5028
|
+
// Misuse: the dispatching resolver routes parameterless calls to the
|
|
5029
|
+
// legacy resolver. Reject so production fails loudly here.
|
|
5030
|
+
reject('ParameterizedSfapJwtAuraResolver requires JwtMintParams. The legacy parameterless path should be served by platformSfapJwtResolver.');
|
|
5031
|
+
return;
|
|
5032
|
+
}
|
|
5033
|
+
const coerced = coerceToSfapParams(params);
|
|
5034
|
+
if ('error' in coerced) {
|
|
5035
|
+
reject(coerced.error);
|
|
5036
|
+
return;
|
|
5037
|
+
}
|
|
5038
|
+
// The mint inputs become the single `requestBody` named param of the
|
|
5039
|
+
// generated Aura method (Aura binds top-level keys to the controller
|
|
5040
|
+
// method's named args). Reuses the HTTP resolver's body builder so both
|
|
5041
|
+
// transports send an identical shape.
|
|
5042
|
+
const requestBody = buildRequestBody(coerced.params);
|
|
5043
|
+
// No fetchImpl / requestInterceptor / CSRF / credentials handling here —
|
|
5044
|
+
// the Aura stack owns session + CSRF. Matches the legacy resolver's call.
|
|
5045
|
+
dispatchAuraAction(`${SFAPController}.${SFAPJwtPostMethod}`, { requestBody }, defaultActionConfig)
|
|
5046
|
+
.then((response) => {
|
|
5047
|
+
const body = response.body;
|
|
5048
|
+
if (!body || typeof body.jwt !== 'string' || typeof body.baseUri !== 'string') {
|
|
5049
|
+
// Never serialize the body into the error — it may carry a JWT.
|
|
5050
|
+
reject('SFAP JWT response missing required fields (jwt, baseUri)');
|
|
5051
|
+
return;
|
|
5052
|
+
}
|
|
5053
|
+
resolve({ jwt: body.jwt, extraInfo: { baseUri: body.baseUri } });
|
|
5054
|
+
})
|
|
5055
|
+
.catch((error) => {
|
|
5056
|
+
// Error mapping ported from the legacy platformSfapJwtResolver
|
|
5057
|
+
// (network-sfap.ts): plain Errors carry a message; non-500
|
|
5058
|
+
// AuraFetchResponses are ConnectInJava errors with a typed body;
|
|
5059
|
+
// 500s carry an { error } body.
|
|
5060
|
+
if (error instanceof Error) {
|
|
5061
|
+
reject(error.message);
|
|
5062
|
+
return;
|
|
5063
|
+
}
|
|
5064
|
+
const { status } = error;
|
|
5065
|
+
if (status !== HttpStatusCode$2.ServerError) {
|
|
5066
|
+
reject(error.body.message);
|
|
5067
|
+
return;
|
|
5068
|
+
}
|
|
5069
|
+
reject(error.body.error);
|
|
5070
|
+
});
|
|
5071
|
+
});
|
|
5072
|
+
}
|
|
5073
|
+
}
|
|
5074
|
+
|
|
4911
5075
|
/**
|
|
4912
5076
|
* Observability / Critical Availability Program (230+)
|
|
4913
5077
|
*
|
|
@@ -5658,7 +5822,9 @@ class PrioritizedConfigService {
|
|
|
5658
5822
|
// ConfigService.set
|
|
5659
5823
|
set(priority, setter) {
|
|
5660
5824
|
this.validated = false;
|
|
5661
|
-
return setter(
|
|
5825
|
+
return setter(
|
|
5826
|
+
this.prioritizedConfigData[priority]
|
|
5827
|
+
);
|
|
5662
5828
|
}
|
|
5663
5829
|
// returns the highest priority value for a given path, undefined if no value
|
|
5664
5830
|
// is defined for the path at any priority
|
|
@@ -5717,7 +5883,7 @@ function getEnvironmentSetting(name) {
|
|
|
5717
5883
|
}
|
|
5718
5884
|
return undefined;
|
|
5719
5885
|
}
|
|
5720
|
-
// version: 1.
|
|
5886
|
+
// version: 1.444.0-86f5a57eb3
|
|
5721
5887
|
|
|
5722
5888
|
/**
|
|
5723
5889
|
* Helpers for reaching the Aura framework from the LDS Aura runtime.
|
|
@@ -5727,6 +5893,14 @@ function getEnvironmentSetting(name) {
|
|
|
5727
5893
|
* `$A` lookup in one place instead of duplicating the `environmentHasAura`
|
|
5728
5894
|
* check across modules.
|
|
5729
5895
|
*/
|
|
5896
|
+
/**
|
|
5897
|
+
* Fires an Aura application-level event (e.g. `aura:invalidSession`). Thin
|
|
5898
|
+
* pass-through to the `aura` framework module so callers depend on this util
|
|
5899
|
+
* rather than importing `aura` directly.
|
|
5900
|
+
*/
|
|
5901
|
+
function dispatchGlobalEvent(...args) {
|
|
5902
|
+
dispatchGlobalEvent$1(...args);
|
|
5903
|
+
}
|
|
5730
5904
|
/**
|
|
5731
5905
|
* Returns `$A.clientService` when running inside an Aura environment, or
|
|
5732
5906
|
* `undefined` otherwise. Defensive: never throws.
|
|
@@ -5997,34 +6171,54 @@ function buildLuvioPageScopedCacheRequestInterceptor() {
|
|
|
5997
6171
|
};
|
|
5998
6172
|
}
|
|
5999
6173
|
|
|
6000
|
-
|
|
6174
|
+
// Two distinct session-expiration cases on the LEX runtime path:
|
|
6175
|
+
// - 401 + INVALID_SESSION_ID — auth token rejected
|
|
6176
|
+
// - 403 + `x-sfdc-csrf-failure: true` — CSRF token rejected, session is dead
|
|
6177
|
+
// Both fire `aura:invalidSession`, which routes the user back to login.
|
|
6178
|
+
//
|
|
6179
|
+
// 403 access denials (INSUFFICIENT_ACCESS / INSUFFICIENT_ACCESS_OR_READONLY) are
|
|
6180
|
+
// intentionally NOT handled here — `aura:noAccess` without a `redirectURL`
|
|
6181
|
+
// triggers AuraClientService.hardRefresh() which is too heavy-handed for routine
|
|
6182
|
+
// "feature not enabled for this org" responses. The wire layer surfaces those
|
|
6183
|
+
// as normal errors; onestore PR #838 (`aura-network-command`) handles the
|
|
6184
|
+
// gack-noise on the Aura action path.
|
|
6185
|
+
function isSessionExpired(status, headers, body) {
|
|
6186
|
+
if (status === 403) {
|
|
6187
|
+
return headers && headers['x-sfdc-csrf-failure'] === 'true';
|
|
6188
|
+
}
|
|
6189
|
+
if (status === 401) {
|
|
6190
|
+
// Connect REST returns errors as `[{ errorCode, ... }, ...]`; Aura Shape A
|
|
6191
|
+
// uses `{ errorCode, ... }`. This interceptor runs before
|
|
6192
|
+
// `buildLuvioErrorBodyNormalizationInterceptor`, so handle both.
|
|
6193
|
+
const errorCode = Array.isArray(body)
|
|
6194
|
+
? body[0] && body[0].errorCode
|
|
6195
|
+
: body && body.errorCode;
|
|
6196
|
+
return errorCode === 'INVALID_SESSION_ID';
|
|
6197
|
+
}
|
|
6198
|
+
return false;
|
|
6199
|
+
}
|
|
6200
|
+
function buildLexRuntimeSessionExpirationResponseInterceptor(logger) {
|
|
6001
6201
|
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}`);
|
|
6202
|
+
const { status } = response;
|
|
6203
|
+
if (status !== 401 && status !== 403)
|
|
6204
|
+
return response;
|
|
6205
|
+
try {
|
|
6206
|
+
const coerced = (await coerceResponseToFetchResponse(response.clone()));
|
|
6207
|
+
if (isSessionExpired(status, coerced.headers, coerced.body)) {
|
|
6208
|
+
logger.warn(`Received ${status} status code from LEX runtime service`);
|
|
6209
|
+
window.setTimeout(() => dispatchGlobalEvent('aura:invalidSession'), 0);
|
|
6015
6210
|
}
|
|
6016
6211
|
}
|
|
6212
|
+
catch (error) {
|
|
6213
|
+
logger.warn(`Error parsing response from LEX runtime service: ${error}`);
|
|
6214
|
+
}
|
|
6017
6215
|
return response;
|
|
6018
6216
|
};
|
|
6019
6217
|
}
|
|
6020
|
-
function
|
|
6218
|
+
function buildLexRuntimeLuvioSessionExpirationResponseInterceptor() {
|
|
6021
6219
|
return async (response) => {
|
|
6022
|
-
if (response.status
|
|
6023
|
-
|
|
6024
|
-
window.setTimeout(() => {
|
|
6025
|
-
dispatchGlobalEvent('aura:invalidSession');
|
|
6026
|
-
}, 0);
|
|
6027
|
-
}
|
|
6220
|
+
if (isSessionExpired(response.status, response.headers, response.body)) {
|
|
6221
|
+
window.setTimeout(() => dispatchGlobalEvent('aura:invalidSession'), 0);
|
|
6028
6222
|
}
|
|
6029
6223
|
return response;
|
|
6030
6224
|
};
|
|
@@ -7203,7 +7397,7 @@ const composedFetchNetworkAdapter = {
|
|
|
7203
7397
|
retry: buildLuvioFetchRetryInterceptor(),
|
|
7204
7398
|
response: [
|
|
7205
7399
|
buildLexRuntimeLuvio5xxStatusResponseInterceptor(),
|
|
7206
|
-
|
|
7400
|
+
buildLexRuntimeLuvioSessionExpirationResponseInterceptor(),
|
|
7207
7401
|
buildLuvioErrorBodyNormalizationInterceptor(),
|
|
7208
7402
|
buildLuvioTransportMarksReceiveInterceptor(),
|
|
7209
7403
|
buildLuvioActionMarksReceiveInterceptor(),
|
|
@@ -7369,9 +7563,106 @@ function buildCsrfRetryInterceptor() {
|
|
|
7369
7563
|
};
|
|
7370
7564
|
}
|
|
7371
7565
|
|
|
7566
|
+
/**
|
|
7567
|
+
* The context-seed key under which a custom command forwards its JWT mint
|
|
7568
|
+
* parameters. The framework's `buildServiceDescriptor` merges the request init's
|
|
7569
|
+
* `__contextSeed` onto the per-request interceptor context, so this interceptor
|
|
7570
|
+
* reads the params off `context[JWT_MINT_PARAMS_SEED_KEY]`.
|
|
7571
|
+
*
|
|
7572
|
+
* This is a cross-team contract: the custom command writes this key, this
|
|
7573
|
+
* interceptor reads it. It is intentionally an opaque key — OneStore does not
|
|
7574
|
+
* define it and never inspects the param shape; the typed shape lives in the
|
|
7575
|
+
* resolver.
|
|
7576
|
+
*/
|
|
7577
|
+
const JWT_MINT_PARAMS_SEED_KEY = 'jwtMintParams';
|
|
7578
|
+
/**
|
|
7579
|
+
* Returns `true` if the fetch arguments already carry an `Authorization` header,
|
|
7580
|
+
* across the three shapes the framework's `setHeader` handles: a `Request`
|
|
7581
|
+
* resource's own headers, an `options.headers` `Headers` instance, or a plain
|
|
7582
|
+
* record. The descriptor's guarded legacy interceptor uses this to skip when the
|
|
7583
|
+
* parameterized interceptor has already authorized the request — avoiding a second
|
|
7584
|
+
* mint and the throw `setHeaderAuthorization` raises on an existing header.
|
|
7585
|
+
*/
|
|
7586
|
+
function hasAuthorizationHeader([resource, options]) {
|
|
7587
|
+
if (resource instanceof Request && resource.headers.has('Authorization')) {
|
|
7588
|
+
return true;
|
|
7589
|
+
}
|
|
7590
|
+
const headers = options?.headers;
|
|
7591
|
+
if (headers === undefined) {
|
|
7592
|
+
return false;
|
|
7593
|
+
}
|
|
7594
|
+
if (headers instanceof Headers) {
|
|
7595
|
+
return headers.has('Authorization');
|
|
7596
|
+
}
|
|
7597
|
+
if (Array.isArray(headers)) {
|
|
7598
|
+
return headers.some(([name]) => name.toLowerCase() === 'authorization');
|
|
7599
|
+
}
|
|
7600
|
+
return Reflect.has(headers, 'Authorization');
|
|
7601
|
+
}
|
|
7602
|
+
/**
|
|
7603
|
+
* Builds the request interceptor that bridges the per-request context seed to the
|
|
7604
|
+
* dispatching SFAP JwtManager for the **parameterized** mint path.
|
|
7605
|
+
*
|
|
7606
|
+
* For a parameterized SFAP command, the context carries `jwtMintParams`. This
|
|
7607
|
+
* interceptor reads them, calls `jwtManager.getJwt(params)` (which the dispatching
|
|
7608
|
+
* resolver routes to the parameterized resolver), attaches the `Authorization`
|
|
7609
|
+
* header, and rewrites the request URL via the minted `baseUri`. The presence of
|
|
7610
|
+
* that `Authorization` header is the signal the descriptor's guarded legacy
|
|
7611
|
+
* interceptor uses to skip — so the legacy path does not mint a second time.
|
|
7612
|
+
*
|
|
7613
|
+
* For a legacy parameterless command the context carries no `jwtMintParams`, so
|
|
7614
|
+
* this interceptor **early-returns on its first line** and the request flows
|
|
7615
|
+
* unchanged to the legacy `buildJwtRequestHeaderInterceptor` — guaranteeing zero
|
|
7616
|
+
* behavior change for non-opted-in adapters.
|
|
7617
|
+
*
|
|
7618
|
+
* Lives in `lds-lightning-platform` (not OneStore) beside the existing SFAP/CSRF
|
|
7619
|
+
* interceptors, per the JWT-parameterization ADR §5: OneStore provides only the
|
|
7620
|
+
* generic interceptor mechanism and the opaque context-seed channel; the service-
|
|
7621
|
+
* specific bridge is a runtime-layer concern.
|
|
7622
|
+
*
|
|
7623
|
+
* @param jwtManager - the dispatching SFAP JwtManager
|
|
7624
|
+
* @param jwtRequestModifier - applies the minted `extraInfo.baseUri` to the request URL
|
|
7625
|
+
*/
|
|
7626
|
+
function buildJwtParameterizationInterceptor(jwtManager, jwtRequestModifier = (_extraInfo, fetchArgs) => fetchArgs) {
|
|
7627
|
+
return (fetchArgs, context) => {
|
|
7628
|
+
const jwtContext = context;
|
|
7629
|
+
const mintParams = jwtContext?.[JWT_MINT_PARAMS_SEED_KEY];
|
|
7630
|
+
// No mint params → not a parameterized request. Do nothing; the legacy
|
|
7631
|
+
// interceptor handles it. This MUST be the first statement so non-opted-in
|
|
7632
|
+
// SFAP commands observe no work at all.
|
|
7633
|
+
if (mintParams === undefined) {
|
|
7634
|
+
return resolvedPromiseLike$2(fetchArgs);
|
|
7635
|
+
}
|
|
7636
|
+
return resolvedPromiseLike$2(jwtManager.getJwt(mintParams)).then((token) => {
|
|
7637
|
+
const fetchArgsWithAuthorization = setHeaderAuthorization(token, fetchArgs);
|
|
7638
|
+
return token.extraInfo
|
|
7639
|
+
? jwtRequestModifier(token.extraInfo, fetchArgsWithAuthorization)
|
|
7640
|
+
: fetchArgsWithAuthorization;
|
|
7641
|
+
});
|
|
7642
|
+
};
|
|
7643
|
+
}
|
|
7644
|
+
|
|
7372
7645
|
const SFAP_BASE_URL = 'api.salesforce.com';
|
|
7646
|
+
function buildDispatchingSfapJwtResolver(legacyResolver, parameterizedResolver) {
|
|
7647
|
+
return {
|
|
7648
|
+
getJwt(params) {
|
|
7649
|
+
if (params === undefined) {
|
|
7650
|
+
return legacyResolver.getJwt();
|
|
7651
|
+
}
|
|
7652
|
+
return parameterizedResolver.getJwt(params);
|
|
7653
|
+
},
|
|
7654
|
+
};
|
|
7655
|
+
}
|
|
7656
|
+
// The parameterized mint is dispatched over **Aura transport**:
|
|
7657
|
+
// the resolver calls the SFAP Lightning JWT Service's auto-generated Aura method
|
|
7658
|
+
// `SalesforceApiPlatformController.postSFAPLightningJwtService`, so session + CSRF
|
|
7659
|
+
// are handled inside the Aura stack. This mirrors the legacy parameterless
|
|
7660
|
+
// `platformSfapJwtResolver`, which already mints over Aura. The minted JWT is then
|
|
7661
|
+
// attached as a Bearer token on the downstream SFAP API request (which stays HTTP).
|
|
7662
|
+
const parameterizedSfapJwtResolver = new ParameterizedSfapJwtAuraResolver();
|
|
7663
|
+
const sfapJwtResolver = buildDispatchingSfapJwtResolver(platformSfapJwtResolver, parameterizedSfapJwtResolver);
|
|
7373
7664
|
const sfapJwtRepository = new JwtRepository();
|
|
7374
|
-
const sfapJwtManager = new JwtManager(sfapJwtRepository,
|
|
7665
|
+
const sfapJwtManager = new JwtManager(sfapJwtRepository, sfapJwtResolver);
|
|
7375
7666
|
function prefetchSfapJwt() {
|
|
7376
7667
|
const maybePromise = sfapJwtManager.getJwt();
|
|
7377
7668
|
if ('then' in maybePromise) {
|
|
@@ -7382,8 +7673,12 @@ function prefetchSfapJwt() {
|
|
|
7382
7673
|
function buildJwtAuthorizedSfapFetchServiceDescriptor(logger) {
|
|
7383
7674
|
const jwtAuthorizedFetchService = buildServiceDescriptor$2({
|
|
7384
7675
|
createContext: createInstrumentationIdContext(),
|
|
7385
|
-
request: [
|
|
7386
|
-
|
|
7676
|
+
request: [
|
|
7677
|
+
buildThirdPartyTrackerRegisterInterceptor(),
|
|
7678
|
+
buildJwtParameterizationInterceptor(sfapJwtManager, buildSfapJwtRequestModifier(logger)),
|
|
7679
|
+
// Guarded so it is skipped once the parameterized interceptor handled the request.
|
|
7680
|
+
buildGuardedLegacyJwtRequestInterceptor(logger),
|
|
7681
|
+
],
|
|
7387
7682
|
finally: [buildThirdPartyTrackerFinishInterceptor()],
|
|
7388
7683
|
});
|
|
7389
7684
|
return {
|
|
@@ -7463,8 +7758,13 @@ function buildUnauthorizedFetchServiceDescriptor() {
|
|
|
7463
7758
|
tags: { authenticationScopes: '' },
|
|
7464
7759
|
};
|
|
7465
7760
|
}
|
|
7466
|
-
|
|
7467
|
-
|
|
7761
|
+
/**
|
|
7762
|
+
* The `JwtRequestModifier` shared by both the legacy and parameterized SFAP
|
|
7763
|
+
* interceptors: it rewrites the request URL's host/protocol to the minted
|
|
7764
|
+
* `extraInfo.baseUri` (only for `api.salesforce.com` resources).
|
|
7765
|
+
*/
|
|
7766
|
+
function buildSfapJwtRequestModifier(logger) {
|
|
7767
|
+
return ({ baseUri }, [resource, request]) => {
|
|
7468
7768
|
if (typeof resource !== 'string' && !(resource instanceof URL)) {
|
|
7469
7769
|
// istanbul ignore else: this will not be tested in NODE_ENV = production for test coverage
|
|
7470
7770
|
if (process.env.NODE_ENV !== 'production') {
|
|
@@ -7482,8 +7782,22 @@ function buildJwtRequestInterceptor(logger) {
|
|
|
7482
7782
|
url.protocol = overrideUrl.protocol;
|
|
7483
7783
|
return [url, request];
|
|
7484
7784
|
};
|
|
7485
|
-
|
|
7486
|
-
|
|
7785
|
+
}
|
|
7786
|
+
function buildJwtRequestInterceptor(logger) {
|
|
7787
|
+
return buildJwtRequestHeaderInterceptor(sfapJwtManager, buildSfapJwtRequestModifier(logger));
|
|
7788
|
+
}
|
|
7789
|
+
/**
|
|
7790
|
+
* Wraps the legacy `buildJwtRequestHeaderInterceptor` with a pass-through guard:
|
|
7791
|
+
* when the parameterized interceptor has already authorized the request (an
|
|
7792
|
+
* `Authorization` header is present), this returns `args` untouched so the legacy
|
|
7793
|
+
* interceptor does not mint a second time or attempt to set a duplicate
|
|
7794
|
+
* Authorization header (which `setHeaderAuthorization` throws on). For every legacy
|
|
7795
|
+
* (non-parameterized) request no Authorization header is present yet, so the legacy
|
|
7796
|
+
* interceptor runs exactly as before — a strict pass-through.
|
|
7797
|
+
*/
|
|
7798
|
+
function buildGuardedLegacyJwtRequestInterceptor(logger) {
|
|
7799
|
+
const legacyInterceptor = buildJwtRequestInterceptor(logger);
|
|
7800
|
+
return (args) => hasAuthorizationHeader(args) ? resolvedPromiseLike$2(args) : legacyInterceptor(args);
|
|
7487
7801
|
}
|
|
7488
7802
|
|
|
7489
7803
|
const PDL_EXECUTE_ASYNC_OPTIONS = {
|
|
@@ -10146,7 +10460,7 @@ function getLexRuntimeDefaultInterceptorConfig(logger) {
|
|
|
10146
10460
|
retry: buildCsrfRetryInterceptor(),
|
|
10147
10461
|
response: [
|
|
10148
10462
|
buildLexRuntime5xxStatusResponseInterceptor(logger),
|
|
10149
|
-
|
|
10463
|
+
buildLexRuntimeSessionExpirationResponseInterceptor(logger),
|
|
10150
10464
|
buildTransportMarksReceiveInterceptor(),
|
|
10151
10465
|
buildActionMarksReceiveInterceptor(),
|
|
10152
10466
|
],
|
|
@@ -10163,7 +10477,7 @@ function buildLexRuntimeAllow5xxFetchServiceDescriptor(logger, retryService) {
|
|
|
10163
10477
|
...config,
|
|
10164
10478
|
// Omit 5xx interceptor - allow 5xx responses to pass through
|
|
10165
10479
|
response: [
|
|
10166
|
-
|
|
10480
|
+
buildLexRuntimeSessionExpirationResponseInterceptor(logger),
|
|
10167
10481
|
buildTransportMarksReceiveInterceptor(),
|
|
10168
10482
|
buildActionMarksReceiveInterceptor(),
|
|
10169
10483
|
],
|
|
@@ -11058,4 +11372,4 @@ function ldsEngineCreator() {
|
|
|
11058
11372
|
}
|
|
11059
11373
|
|
|
11060
11374
|
export { LexRequestStrategy, PdlPrefetcherEventType, PdlRequestPriority, buildPredictorForContext, configService, ldsEngineCreator as default, initializeLDS, initializeOneStore, notifyUpdateAvailableFactory, registerRequestStrategy, saveRequestAsPrediction, subscribeToPrefetcherEvents, unregisterRequestStrategy, whenPredictionsReady };
|
|
11061
|
-
// version: 1.
|
|
11375
|
+
// version: 1.444.0-a7f42f9edf
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
* `$A` lookup in one place instead of duplicating the `environmentHasAura`
|
|
7
7
|
* check across modules.
|
|
8
8
|
*/
|
|
9
|
+
import { dispatchGlobalEvent as auraDispatchGlobalEvent } from 'aura';
|
|
10
|
+
/**
|
|
11
|
+
* Fires an Aura application-level event (e.g. `aura:invalidSession`). Thin
|
|
12
|
+
* pass-through to the `aura` framework module so callers depend on this util
|
|
13
|
+
* rather than importing `aura` directly.
|
|
14
|
+
*/
|
|
15
|
+
export declare function dispatchGlobalEvent(...args: Parameters<typeof auraDispatchGlobalEvent>): void;
|
|
9
16
|
/**
|
|
10
17
|
* The subset of the Aura client service LDS reaches for. Methods are optional
|
|
11
18
|
* because availability depends on the host's Aura version and server gates.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { type JwtResolver } from '@conduit-client/jwt-manager';
|
|
1
2
|
import { type FetchServiceDescriptor } from '@conduit-client/service-fetch-network/v1';
|
|
3
|
+
import { type ExtraInfo } from '../network-sfap';
|
|
2
4
|
import { type LoggerService } from '@conduit-client/utils';
|
|
5
|
+
export declare function buildDispatchingSfapJwtResolver(legacyResolver: JwtResolver<ExtraInfo>, parameterizedResolver: JwtResolver<ExtraInfo>): JwtResolver<ExtraInfo>;
|
|
3
6
|
export declare function prefetchSfapJwt(): Promise<undefined>;
|
|
4
7
|
export declare function buildJwtAuthorizedSfapFetchServiceDescriptor(logger: LoggerService): FetchServiceDescriptor;
|
|
5
8
|
/**
|
|
@@ -2,6 +2,7 @@ import type { FetchResponse, ResourceRequest, ResourceRequestContext } from '@lu
|
|
|
2
2
|
import type { JwtResolver } from '@conduit-client/jwt-manager';
|
|
3
3
|
export declare const SFAPController = "SalesforceApiPlatformController";
|
|
4
4
|
export declare const SFAPJwtMethod = "getSFAPLightningJwtService";
|
|
5
|
+
export declare const SFAPJwtPostMethod = "postSFAPLightningJwtService";
|
|
5
6
|
export type ExtraInfo = {
|
|
6
7
|
baseUri: string;
|
|
7
8
|
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { JwtMintParams, JwtResolver } from '@conduit-client/jwt-manager';
|
|
2
|
+
import { type ParameterizedSfapExtraInfo } from './sfap-jwt-mint-params';
|
|
3
|
+
/**
|
|
4
|
+
* Parameterized SFAP JWT resolver that mints over **Aura transport** instead of a
|
|
5
|
+
* direct HTTP `fetch`.
|
|
6
|
+
*
|
|
7
|
+
* It dispatches the SFAP Lightning JWT Service's parameterized POST via its
|
|
8
|
+
* auto-generated Aura controller method
|
|
9
|
+
* `SalesforceApiPlatformController.postSFAPLightningJwtService` (generated by
|
|
10
|
+
* `@ConnectSignature(..., generateAuraMethod = true)` on the Connect resource).
|
|
11
|
+
* The mint inputs ride as the single `requestBody` named param, in the same
|
|
12
|
+
* `{ scopes, dynamicParameters: { items } }` shape the HTTP resolver POSTs — built
|
|
13
|
+
* by the shared {@link buildRequestBody}, so the two transports stay in lockstep.
|
|
14
|
+
*
|
|
15
|
+
* Why Aura (not the HTTP resolver): the mint endpoint is a same-origin core
|
|
16
|
+
* resource, and routing it over Aura keeps session/CSRF handling inside the Aura
|
|
17
|
+
* stack rather than issuing a credentialed cross-cutting `fetch` from the client.
|
|
18
|
+
* This mirrors the legacy parameterless `platformSfapJwtResolver` in
|
|
19
|
+
* `network-sfap.ts`, which already mints over Aura via the `getSFAPLightningJwtService`
|
|
20
|
+
* generated method — this is the parameterized sibling of that call.
|
|
21
|
+
*
|
|
22
|
+
* A `JwtResolver` is invoked directly by `JwtManager` (not through Luvio's
|
|
23
|
+
* `appRouter`/`ResourceRequest` pipeline), so the correct mechanism is a direct
|
|
24
|
+
* named-controller `dispatchAuraAction`, not the `auraNetworkAdapter`/connect-route
|
|
25
|
+
* table. The SFAP JWT endpoint is not registered as a connect-over-Aura route, and
|
|
26
|
+
* a resolver has no `ResourceRequest` for the router to look up.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ParameterizedSfapJwtAuraResolver implements JwtResolver<ParameterizedSfapExtraInfo> {
|
|
29
|
+
getJwt(params?: JwtMintParams): Promise<{
|
|
30
|
+
jwt: string;
|
|
31
|
+
extraInfo: ParameterizedSfapExtraInfo;
|
|
32
|
+
}>;
|
|
33
|
+
}
|
|
34
|
+
export declare function buildParameterizedSfapJwtAuraResolver(): ParameterizedSfapJwtAuraResolver;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { FetchParameters, RequestInterceptor } from '@conduit-client/service-fetch-network/v1';
|
|
2
|
+
import { type JwtRequestModifier } from '@conduit-client/service-fetch-network/v1';
|
|
3
|
+
import type { JwtManager } from '@conduit-client/jwt-manager';
|
|
4
|
+
import type { ExtraInfo } from '../network-sfap';
|
|
5
|
+
/**
|
|
6
|
+
* The context-seed key under which a custom command forwards its JWT mint
|
|
7
|
+
* parameters. The framework's `buildServiceDescriptor` merges the request init's
|
|
8
|
+
* `__contextSeed` onto the per-request interceptor context, so this interceptor
|
|
9
|
+
* reads the params off `context[JWT_MINT_PARAMS_SEED_KEY]`.
|
|
10
|
+
*
|
|
11
|
+
* This is a cross-team contract: the custom command writes this key, this
|
|
12
|
+
* interceptor reads it. It is intentionally an opaque key — OneStore does not
|
|
13
|
+
* define it and never inspects the param shape; the typed shape lives in the
|
|
14
|
+
* resolver.
|
|
15
|
+
*/
|
|
16
|
+
export declare const JWT_MINT_PARAMS_SEED_KEY = "jwtMintParams";
|
|
17
|
+
/**
|
|
18
|
+
* Returns `true` if the fetch arguments already carry an `Authorization` header,
|
|
19
|
+
* across the three shapes the framework's `setHeader` handles: a `Request`
|
|
20
|
+
* resource's own headers, an `options.headers` `Headers` instance, or a plain
|
|
21
|
+
* record. The descriptor's guarded legacy interceptor uses this to skip when the
|
|
22
|
+
* parameterized interceptor has already authorized the request — avoiding a second
|
|
23
|
+
* mint and the throw `setHeaderAuthorization` raises on an existing header.
|
|
24
|
+
*/
|
|
25
|
+
export declare function hasAuthorizationHeader([resource, options]: FetchParameters): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Builds the request interceptor that bridges the per-request context seed to the
|
|
28
|
+
* dispatching SFAP JwtManager for the **parameterized** mint path.
|
|
29
|
+
*
|
|
30
|
+
* For a parameterized SFAP command, the context carries `jwtMintParams`. This
|
|
31
|
+
* interceptor reads them, calls `jwtManager.getJwt(params)` (which the dispatching
|
|
32
|
+
* resolver routes to the parameterized resolver), attaches the `Authorization`
|
|
33
|
+
* header, and rewrites the request URL via the minted `baseUri`. The presence of
|
|
34
|
+
* that `Authorization` header is the signal the descriptor's guarded legacy
|
|
35
|
+
* interceptor uses to skip — so the legacy path does not mint a second time.
|
|
36
|
+
*
|
|
37
|
+
* For a legacy parameterless command the context carries no `jwtMintParams`, so
|
|
38
|
+
* this interceptor **early-returns on its first line** and the request flows
|
|
39
|
+
* unchanged to the legacy `buildJwtRequestHeaderInterceptor` — guaranteeing zero
|
|
40
|
+
* behavior change for non-opted-in adapters.
|
|
41
|
+
*
|
|
42
|
+
* Lives in `lds-lightning-platform` (not OneStore) beside the existing SFAP/CSRF
|
|
43
|
+
* interceptors, per the JWT-parameterization ADR §5: OneStore provides only the
|
|
44
|
+
* generic interceptor mechanism and the opaque context-seed channel; the service-
|
|
45
|
+
* specific bridge is a runtime-layer concern.
|
|
46
|
+
*
|
|
47
|
+
* @param jwtManager - the dispatching SFAP JwtManager
|
|
48
|
+
* @param jwtRequestModifier - applies the minted `extraInfo.baseUri` to the request URL
|
|
49
|
+
*/
|
|
50
|
+
export declare function buildJwtParameterizationInterceptor(jwtManager: JwtManager<unknown, ExtraInfo>, jwtRequestModifier?: JwtRequestModifier): RequestInterceptor;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { LoggerService } from '@conduit-client/utils';
|
|
2
2
|
import type { ResponseInterceptor } from '@conduit-client/service-fetch-network/v1';
|
|
3
3
|
import type { ResponseInterceptor as LuvioResponseInterceptor } from '@salesforce/lds-network-fetch';
|
|
4
|
-
export declare function
|
|
5
|
-
export declare function
|
|
4
|
+
export declare function buildLexRuntimeSessionExpirationResponseInterceptor(logger: LoggerService): ResponseInterceptor;
|
|
5
|
+
export declare function buildLexRuntimeLuvioSessionExpirationResponseInterceptor(): LuvioResponseInterceptor;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { JwtMintParams } from '@conduit-client/jwt-manager';
|
|
2
|
+
/**
|
|
3
|
+
* Typed shape of the params the SFAP Lightning JWT Service understands.
|
|
4
|
+
* Lives in the resolver layer because OneStore is param-shape-agnostic; it
|
|
5
|
+
* sees only an opaque `JwtMintParams` bag and stable-JSON-stringifies it for
|
|
6
|
+
* cache keying.
|
|
7
|
+
*/
|
|
8
|
+
export type SfapJwtMintParams = {
|
|
9
|
+
scopes?: string[];
|
|
10
|
+
dynamicParams?: Record<string, string>;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The `extraInfo` the SFAP JWT resolver returns alongside the minted token: the
|
|
14
|
+
* per-tenant base URI the downstream SFAP API request is rewritten to.
|
|
15
|
+
*/
|
|
16
|
+
export type ParameterizedSfapExtraInfo = {
|
|
17
|
+
baseUri: string;
|
|
18
|
+
};
|
|
19
|
+
type DynamicParameterItem = {
|
|
20
|
+
name: string;
|
|
21
|
+
value: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* The SFAP Lightning JWT Service mint request body. Sent as the `requestBody`
|
|
25
|
+
* named param of the `postSFAPLightningJwtService` Aura controller method.
|
|
26
|
+
* Matches the server's `SFAPLightningJwtServiceInputRepresentation`: `scopes` is
|
|
27
|
+
* a single space-delimited string; `dynamicParameters` is `{ items: [{ name, value }] }`.
|
|
28
|
+
*/
|
|
29
|
+
export type SfapJwtRequestBody = {
|
|
30
|
+
scopes?: string;
|
|
31
|
+
dynamicParameters?: {
|
|
32
|
+
items: DynamicParameterItem[];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Normalize SFAP-shaped params into the opaque `JwtMintParams` bag that callers
|
|
37
|
+
* hand to `JwtManager.getJwt(params)`. Scopes are sorted because they are
|
|
38
|
+
* semantically a set — without this, `['a', 'b']` and `['b', 'a']` would cache
|
|
39
|
+
* as separate entries (OneStore treats arrays as ordered under stable-JSON
|
|
40
|
+
* serialization; see ADR "JWT Parameterization" §2).
|
|
41
|
+
*
|
|
42
|
+
* MANDATORY CONSUMER ENTRY POINT. Every consumer that mints a parameterized
|
|
43
|
+
* SFAP JWT MUST assemble its params through this function before calling the
|
|
44
|
+
* manager. The cache key is derived by `JwtManager` from the caller's params
|
|
45
|
+
* (`cacheKeyFor(params)`) *before* the resolver runs — so the resolver cannot
|
|
46
|
+
* normalize after the fact. Set-stable caching therefore depends on the caller
|
|
47
|
+
* routing params through here. Do NOT sort inside the resolver: that would only
|
|
48
|
+
* reorder the wire body, not the cache key, and mutating the caller's params
|
|
49
|
+
* mid-call would desync the in-flight-dedup key from the stored-token key.
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildSfapJwtMintParams(params: SfapJwtMintParams): JwtMintParams;
|
|
52
|
+
export type SfapParamsResult = {
|
|
53
|
+
params: SfapJwtMintParams;
|
|
54
|
+
} | {
|
|
55
|
+
error: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Validate and narrow an opaque `JwtMintParams` bag to the SFAP-shaped subset the
|
|
59
|
+
* resolver forwards. Returns `{ error }` (surfaced as a resolver rejection) for a
|
|
60
|
+
* malformed bag rather than throwing.
|
|
61
|
+
*/
|
|
62
|
+
export declare function coerceToSfapParams(params: JwtMintParams): SfapParamsResult;
|
|
63
|
+
/**
|
|
64
|
+
* Build the SFAP mint request body from the coerced params: `scopes` joined into a
|
|
65
|
+
* single space-delimited string, `dynamicParams` mapped to `dynamicParameters.items`.
|
|
66
|
+
* Empty scopes / dynamic params are omitted.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildRequestBody(params: SfapJwtMintParams): SfapJwtRequestBody;
|
|
69
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-aura",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.444.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS engine for Aura runtime.",
|
|
6
6
|
"main": "dist/ldsEngineCreator.js",
|
|
@@ -34,61 +34,62 @@
|
|
|
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.23.1",
|
|
38
|
+
"@conduit-client/tools-core": "3.23.1",
|
|
39
|
+
"@salesforce/lds-adapters-apex": "^1.444.0",
|
|
40
|
+
"@salesforce/lds-adapters-uiapi": "^1.444.0",
|
|
41
|
+
"@salesforce/lds-ads-bridge": "^1.444.0",
|
|
42
|
+
"@salesforce/lds-aura-storage": "^1.444.0",
|
|
43
|
+
"@salesforce/lds-bindings": "^1.444.0",
|
|
44
|
+
"@salesforce/lds-instrumentation": "^1.444.0",
|
|
45
|
+
"@salesforce/lds-network-adapter": "^1.444.0",
|
|
46
|
+
"@salesforce/lds-network-aura": "^1.444.0",
|
|
47
|
+
"@salesforce/lds-network-fetch": "^1.444.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/
|
|
63
|
-
"@conduit-client/service-
|
|
64
|
-
"@conduit-client/service-bindings-
|
|
65
|
-
"@conduit-client/service-
|
|
66
|
-
"@conduit-client/service-cache
|
|
67
|
-
"@conduit-client/service-cache-
|
|
68
|
-
"@conduit-client/service-
|
|
69
|
-
"@conduit-client/service-
|
|
70
|
-
"@conduit-client/service-
|
|
71
|
-
"@conduit-client/service-
|
|
72
|
-
"@conduit-client/service-
|
|
73
|
-
"@conduit-client/service-
|
|
74
|
-
"@conduit-client/service-
|
|
75
|
-
"@conduit-client/
|
|
76
|
-
"@
|
|
77
|
-
"@luvio/network-adapter-
|
|
51
|
+
"@conduit-client/command-aura-graphql-normalized-cache-control": "3.23.1",
|
|
52
|
+
"@conduit-client/command-aura-network": "3.23.1",
|
|
53
|
+
"@conduit-client/command-aura-normalized-cache-control": "3.23.1",
|
|
54
|
+
"@conduit-client/command-aura-resource-cache-control": "3.23.1",
|
|
55
|
+
"@conduit-client/command-fetch-network": "3.23.1",
|
|
56
|
+
"@conduit-client/command-http-graphql-normalized-cache-control": "3.23.1",
|
|
57
|
+
"@conduit-client/command-http-normalized-cache-control": "3.23.1",
|
|
58
|
+
"@conduit-client/command-ndjson": "3.23.1",
|
|
59
|
+
"@conduit-client/command-network": "3.23.1",
|
|
60
|
+
"@conduit-client/command-sse": "3.23.1",
|
|
61
|
+
"@conduit-client/command-streaming": "3.23.1",
|
|
62
|
+
"@conduit-client/jwt-manager": "3.23.1",
|
|
63
|
+
"@conduit-client/service-aura-network": "3.23.1",
|
|
64
|
+
"@conduit-client/service-bindings-imperative": "3.23.1",
|
|
65
|
+
"@conduit-client/service-bindings-lwc": "3.23.1",
|
|
66
|
+
"@conduit-client/service-cache": "3.23.1",
|
|
67
|
+
"@conduit-client/service-cache-control": "3.23.1",
|
|
68
|
+
"@conduit-client/service-cache-inclusion-policy": "3.23.1",
|
|
69
|
+
"@conduit-client/service-config": "3.23.1",
|
|
70
|
+
"@conduit-client/service-feature-flags": "3.23.1",
|
|
71
|
+
"@conduit-client/service-fetch-network": "3.23.1",
|
|
72
|
+
"@conduit-client/service-instrument-command": "3.23.1",
|
|
73
|
+
"@conduit-client/service-pubsub": "3.23.1",
|
|
74
|
+
"@conduit-client/service-renewable-resource-manager": "3.23.1",
|
|
75
|
+
"@conduit-client/service-store": "3.23.1",
|
|
76
|
+
"@conduit-client/utils": "3.23.1",
|
|
77
|
+
"@luvio/network-adapter-composable": "0.161.0",
|
|
78
|
+
"@luvio/network-adapter-fetch": "0.161.0",
|
|
78
79
|
"@lwc/state": "^0.29.0",
|
|
79
|
-
"@salesforce/lds-adapters-onestore-graphql": "^1.
|
|
80
|
+
"@salesforce/lds-adapters-onestore-graphql": "^1.444.0",
|
|
80
81
|
"@salesforce/lds-adapters-uiapi-lex": "^1.415.0",
|
|
81
|
-
"@salesforce/lds-durable-storage": "^1.
|
|
82
|
-
"@salesforce/lds-luvio-service": "^1.
|
|
83
|
-
"@salesforce/lds-luvio-uiapi-records-service": "^1.
|
|
82
|
+
"@salesforce/lds-durable-storage": "^1.444.0",
|
|
83
|
+
"@salesforce/lds-luvio-service": "^1.444.0",
|
|
84
|
+
"@salesforce/lds-luvio-uiapi-records-service": "^1.444.0"
|
|
84
85
|
},
|
|
85
86
|
"luvioBundlesize": [
|
|
86
87
|
{
|
|
87
88
|
"path": "./dist/ldsEngineCreator.js",
|
|
88
89
|
"maxSize": {
|
|
89
|
-
"none": "
|
|
90
|
+
"none": "410 kB",
|
|
90
91
|
"min": "190 kB",
|
|
91
|
-
"compressed": "
|
|
92
|
+
"compressed": "71 kB"
|
|
92
93
|
}
|
|
93
94
|
}
|
|
94
95
|
],
|