@salesforce/lds-runtime-webruntime 1.369.0 → 1.371.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.
@@ -15,8 +15,11 @@
15
15
  import { getInstrumentation } from 'o11y/client';
16
16
  import { setServices } from 'force/luvioServiceProvisioner1';
17
17
  export { default, resolve, setServices } from 'force/luvioServiceProvisioner1';
18
- import { executeGlobalControllerRawResponse } from 'aura';
19
18
  import { getSfapJwt } from 'force/clwrSfapExchange';
19
+ import language from '@salesforce/i18n/lang';
20
+ import isDesignMode from '@app/isDesignMode';
21
+ import isPreviewMode from '@app/isPreviewMode';
22
+ import authenticationCookieName from '@app/authenticationCookieName';
20
23
 
21
24
  /*!
22
25
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -483,6 +486,38 @@ function setOverlaps(setA, setB) {
483
486
  }
484
487
  return false;
485
488
  }
489
+ class CacheControlRequestRunner {
490
+ constructor(readFromCache, requestFromNetwork, writeToCache) {
491
+ this.readFromCacheInternal = readFromCache;
492
+ this.requestFromNetworkInternal = requestFromNetwork;
493
+ this.writeToCacheInternal = writeToCache;
494
+ }
495
+ readFromCache(cache) {
496
+ const resultPromise = this.readFromCacheInternal(cache);
497
+ return resultPromise.then((result) => {
498
+ if (result.isErr()) {
499
+ return err(result.error);
500
+ }
501
+ this.returnData = result;
502
+ return ok$1(void 0);
503
+ });
504
+ }
505
+ requestFromNetwork() {
506
+ const that = this;
507
+ return async function* () {
508
+ const result = await that.requestFromNetworkInternal();
509
+ if (result.isErr()) {
510
+ that.networkError = result;
511
+ } else {
512
+ that.networkData = result;
513
+ }
514
+ yield result;
515
+ }();
516
+ }
517
+ writeToCache(cache, networkResult) {
518
+ return this.writeToCacheInternal(cache, networkResult);
519
+ }
520
+ }
486
521
  class CacheControlCommand extends BaseCommand {
487
522
  constructor(services) {
488
523
  super();
@@ -502,57 +537,48 @@ class CacheControlCommand extends BaseCommand {
502
537
  this.cacheControlStrategyConfig,
503
538
  overrides
504
539
  );
505
- let returnData;
506
- let returnError;
507
- const requestRunner = {
508
- readFromCache: (cache) => {
509
- const resultPromise2 = this.buildResultWithSubscribe(cache);
510
- return resultPromise2.then((result) => {
511
- if (result.isErr()) {
512
- return err(result.error);
513
- }
514
- returnData = result;
515
- return ok$1(void 0);
516
- });
517
- },
518
- requestFromNetwork: () => {
519
- const that = this;
520
- return async function* () {
521
- const result = await that.requestFromNetwork();
522
- if (result.isErr()) {
523
- returnError = result;
524
- }
525
- yield result;
526
- }();
527
- },
528
- writeToCache: (cache, networkResult) => {
529
- return this.writeToCacheAndRecordKeys(cache, networkResult);
530
- }
531
- };
540
+ const requestRunner = this.buildRequestRunner();
532
541
  const resultPromise = this.services.cacheController.execute(mergedCacheControlConfig, requestRunner, {
533
542
  instrumentationAttributes: this.instrumentationAttributes
534
543
  });
535
544
  return resultPromise.then((result) => {
536
- return this.publishUpdatedKeys().then(() => {
537
- if (returnError) {
538
- return returnError;
539
- }
540
- if (result.isErr()) {
541
- return err(result.error);
542
- }
543
- if (this.subscriptions.length > 0) {
544
- this.subscribeToKeysUsed();
545
- }
546
- if (returnData === void 0) {
547
- return err(new Error("Cache miss after fetching from network"));
545
+ return this.handleCacheControllerResult(result, requestRunner);
546
+ });
547
+ }
548
+ handleCacheControllerResult(result, requestRunner) {
549
+ const { networkError, networkData, returnData } = requestRunner;
550
+ return this.publishUpdatedKeys().then(() => {
551
+ if (networkError) {
552
+ return networkError;
553
+ }
554
+ if (result.isErr()) {
555
+ if (networkData) {
556
+ return this.constructSubscribableResult(networkData.value);
548
557
  }
549
- if (returnData.isOk() && this.lastEmittedData === void 0) {
550
- this.lastEmittedData = returnData.value.data;
558
+ return err(result.error);
559
+ }
560
+ if (this.subscriptions.length > 0) {
561
+ this.subscribeToKeysUsed();
562
+ }
563
+ if (returnData === void 0) {
564
+ if (networkData) {
565
+ return this.constructSubscribableResult(networkData.value);
551
566
  }
552
- return returnData;
553
- });
567
+ return err(new Error("Cache miss after fetching from network"));
568
+ }
569
+ if (returnData.isOk() && this.lastEmittedData === void 0) {
570
+ this.lastEmittedData = returnData.value.data;
571
+ }
572
+ return returnData;
554
573
  });
555
574
  }
575
+ buildRequestRunner() {
576
+ return new CacheControlRequestRunner(
577
+ (cache) => this.buildResultWithSubscribe(cache),
578
+ () => this.requestFromNetwork(),
579
+ (cache, networkResult) => this.writeToCacheAndRecordKeys(cache, networkResult)
580
+ );
581
+ }
556
582
  publishUpdatedKeys() {
557
583
  if (this.services.pubSub) {
558
584
  if (this.keysUpdated !== void 0 && this.keysUpdated.size > 0) {
@@ -623,14 +649,18 @@ class CacheControlCommand extends BaseCommand {
623
649
  } else {
624
650
  const data = readResult.value;
625
651
  this.keysUsed = recordableCache.keysRead;
626
- return ok$1({
627
- data,
628
- subscribe: this.buildSubscribe(),
629
- refresh: () => this.refresh()
630
- });
652
+ return this.constructSubscribableResult(data);
631
653
  }
632
654
  });
633
655
  }
656
+ constructSubscribableResult(data) {
657
+ return ok$1({
658
+ data,
659
+ // this cast is in case we need to return Network data as a fallback for caching errors
660
+ subscribe: this.buildSubscribe(),
661
+ refresh: () => this.refresh()
662
+ });
663
+ }
634
664
  /**
635
665
  * Builds a function that subscribes to cache changes via the pubsub service. Whenever
636
666
  * relevant cache updates occur, it re-reads the data and compares it against
@@ -2784,6 +2814,75 @@ const platformSfapJwtResolver = {
2784
2814
  },
2785
2815
  };
2786
2816
 
2817
+ const METHODS_WITH_CSRF = ['POST', 'PATCH', 'PUT', 'DELETE'];
2818
+ /**
2819
+ * Webruntime request interceptor that modifies outgoing HTTP requests with standard
2820
+ * query parameters and security headers. This ensures the api calls for onestore adapters
2821
+ * follow the same pattern as the equivalent luvio api calls for all CLWR endpoints.
2822
+ *
2823
+ * This interceptor:
2824
+ * - Adds language query parameter from i18n settings
2825
+ * - Adds asGuest parameter based on design/preview mode and SID cookie presence
2826
+ * - Adds htmlEncode=false query parameter (since this is an api call by definition)
2827
+ * - For POST/PATCH/PUT/DELETE requests, adds CSRF token to headers
2828
+ *
2829
+ * @param {FetchParameters} args - The fetch parameters array containing [url, requestInit]
2830
+ * @returns Promise-like resolved with the modified fetch parameters
2831
+ *
2832
+ * @example
2833
+ * ```typescript
2834
+ * const modifiedArgs = await webruntimeRequestInterceptor(['/api/data', { method: 'GET' }]);
2835
+ * // URL will have ?language=en_US&asGuest=false&htmlEncode=false appended
2836
+ * ```
2837
+ */
2838
+ async function webruntimeRequestInterceptor(args) {
2839
+ const [url, requestInit] = args;
2840
+ if (!(typeof url === 'string' || url instanceof URL)) {
2841
+ return resolvedPromiseLike$3(args);
2842
+ }
2843
+ const urlObj = url instanceof URL ? url : new URL(url, location?.href);
2844
+ urlObj.searchParams.append('language', language);
2845
+ urlObj.searchParams.append('asGuest', getAsGuestParamValue().toString());
2846
+ urlObj.searchParams.append('htmlEncode', 'false');
2847
+ // Update the args array with the modified URL string
2848
+ args[0] = urlObj;
2849
+ if (requestInit?.method && METHODS_WITH_CSRF.includes(requestInit.method)) {
2850
+ await addCSRFToken(requestInit);
2851
+ }
2852
+ return resolvedPromiseLike$3(args);
2853
+ }
2854
+ function hasSidCookie() {
2855
+ const cookies = document.cookie.split(';');
2856
+ return cookies.some((cookie) => {
2857
+ const [name] = cookie.trim().split('=');
2858
+ return name === authenticationCookieName;
2859
+ });
2860
+ }
2861
+ function getAsGuestParamValue() {
2862
+ // authenticationCookieName (__Secure-has-sid) is set in design mode or preview mode
2863
+ if (isDesignMode || isPreviewMode) {
2864
+ return false;
2865
+ }
2866
+ return !hasSidCookie();
2867
+ }
2868
+ async function addCSRFToken(params) {
2869
+ const { csrfToken } = await getUser();
2870
+ if (!params.headers) {
2871
+ params.headers = {};
2872
+ }
2873
+ if (csrfToken) {
2874
+ params.headers['CSRF-Token'] = csrfToken;
2875
+ }
2876
+ }
2877
+ async function getUser() {
2878
+ if (typeof window === 'undefined') {
2879
+ // always make API calls as guest on the server
2880
+ return { isGuest: true, id: null, csrfToken: null };
2881
+ }
2882
+ const { default: user } = await import('@app/user');
2883
+ return user;
2884
+ }
2885
+
2787
2886
  const SFAP_BASE_URL = 'api.salesforce.com';
2788
2887
  const sfapJwtRepository = new JwtRepository();
2789
2888
  const sfapJwtManager = new JwtManager(sfapJwtRepository, platformSfapJwtResolver);
@@ -2850,8 +2949,8 @@ function buildCopilotFetchServiceDescriptor(logger) {
2850
2949
  tags: { specialHacksFor: 'copilot' },
2851
2950
  };
2852
2951
  }
2853
- function buildUnauthorizedFetchServiceDescriptor() {
2854
- const fetchService = buildServiceDescriptor();
2952
+ function buildDefaultFetchServiceDescriptor() {
2953
+ const fetchService = buildServiceDescriptor({ request: [webruntimeRequestInterceptor] });
2855
2954
  return {
2856
2955
  ...fetchService,
2857
2956
  tags: { authenticationScopes: '' },
@@ -2880,23 +2979,15 @@ function buildJwtRequestInterceptor(logger) {
2880
2979
  return jwtRequestHeaderInterceptor;
2881
2980
  }
2882
2981
 
2883
- function buildAuraNetworkService() {
2884
- return {
2885
- type: 'auraNetwork',
2886
- version: '1.0',
2887
- service: executeGlobalControllerRawResponse,
2888
- };
2889
- }
2890
2982
  const loggerService = new ConsoleLogger$1('ERROR');
2891
2983
  const cacheServiceDescriptor = buildServiceDescriptor$4();
2892
2984
  const instrumentationServiceDescriptor = buildServiceDescriptor$5(loggerService);
2893
2985
  const inMemoryCacheInclusionPolicyServiceDescriptor = buildInMemoryCacheInclusionPolicyService(cacheServiceDescriptor.service);
2894
2986
  const services = [
2895
2987
  instrumentationServiceDescriptor,
2896
- buildUnauthorizedFetchServiceDescriptor(),
2988
+ buildDefaultFetchServiceDescriptor(),
2897
2989
  buildJwtAuthorizedSfapFetchServiceDescriptor(loggerService),
2898
2990
  buildCopilotFetchServiceDescriptor(loggerService),
2899
- buildAuraNetworkService(),
2900
2991
  buildServiceDescriptor$6(instrumentationServiceDescriptor.service),
2901
2992
  buildServiceDescriptor$3(cacheServiceDescriptor.service, inMemoryCacheInclusionPolicyServiceDescriptor.service),
2902
2993
  buildServiceDescriptor$d(),
@@ -2911,4 +3002,4 @@ const services = [
2911
3002
  buildServiceDescriptor$2(),
2912
3003
  ];
2913
3004
  setServices(services);
2914
- // version: 1.369.0-b61b56bd49
3005
+ // version: 1.371.0-e11a80989c
@@ -0,0 +1,22 @@
1
+ import { type FetchParameters } from '@luvio/service-fetch-network/v1';
2
+ /**
3
+ * Webruntime request interceptor that modifies outgoing HTTP requests with standard
4
+ * query parameters and security headers. This ensures the api calls for onestore adapters
5
+ * follow the same pattern as the equivalent luvio api calls for all CLWR endpoints.
6
+ *
7
+ * This interceptor:
8
+ * - Adds language query parameter from i18n settings
9
+ * - Adds asGuest parameter based on design/preview mode and SID cookie presence
10
+ * - Adds htmlEncode=false query parameter (since this is an api call by definition)
11
+ * - For POST/PATCH/PUT/DELETE requests, adds CSRF token to headers
12
+ *
13
+ * @param {FetchParameters} args - The fetch parameters array containing [url, requestInit]
14
+ * @returns Promise-like resolved with the modified fetch parameters
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const modifiedArgs = await webruntimeRequestInterceptor(['/api/data', { method: 'GET' }]);
19
+ * // URL will have ?language=en_US&asGuest=false&htmlEncode=false appended
20
+ * ```
21
+ */
22
+ export declare function webruntimeRequestInterceptor(args: FetchParameters): Promise<[input: RequestInfo | URL, init?: RequestInit | undefined]>;
@@ -7,4 +7,4 @@ export declare function buildJwtAuthorizedSfapFetchServiceDescriptor(logger: Log
7
7
  * copilot commands.
8
8
  */
9
9
  export declare function buildCopilotFetchServiceDescriptor(logger: LoggerService): FetchServiceDescriptor;
10
- export declare function buildUnauthorizedFetchServiceDescriptor(): FetchServiceDescriptor;
10
+ export declare function buildDefaultFetchServiceDescriptor(): FetchServiceDescriptor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-runtime-webruntime",
3
- "version": "1.369.0",
3
+ "version": "1.371.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS engine for Webruntime runtime",
6
6
  "main": "dist/ldsWebruntimeOneStoreInit.js",
@@ -35,33 +35,33 @@
35
35
  "ready": "yarn build && jest --collectCoverage && yarn test:size && yarn release:corejar"
36
36
  },
37
37
  "devDependencies": {
38
- "@luvio/service-provisioner": "5.43.1",
39
- "@luvio/tools-core": "5.43.1",
38
+ "@luvio/service-provisioner": "5.44.0",
39
+ "@luvio/tools-core": "5.44.0",
40
40
  "jwt-encode": "1.0.1"
41
41
  },
42
42
  "dependencies": {
43
- "@luvio/command-aura-network": "5.43.1",
44
- "@luvio/command-aura-normalized-cache-control": "5.43.1",
45
- "@luvio/command-aura-resource-cache-control": "5.43.1",
46
- "@luvio/command-fetch-network": "5.43.1",
47
- "@luvio/command-http-normalized-cache-control": "5.43.1",
48
- "@luvio/command-ndjson": "5.43.1",
49
- "@luvio/command-network": "5.43.1",
50
- "@luvio/command-sse": "5.43.1",
51
- "@luvio/command-streaming": "5.43.1",
52
- "@luvio/jwt-manager": "5.43.1",
43
+ "@luvio/command-aura-network": "5.44.0",
44
+ "@luvio/command-aura-normalized-cache-control": "5.44.0",
45
+ "@luvio/command-aura-resource-cache-control": "5.44.0",
46
+ "@luvio/command-fetch-network": "5.44.0",
47
+ "@luvio/command-http-normalized-cache-control": "5.44.0",
48
+ "@luvio/command-ndjson": "5.44.0",
49
+ "@luvio/command-network": "5.44.0",
50
+ "@luvio/command-sse": "5.44.0",
51
+ "@luvio/command-streaming": "5.44.0",
52
+ "@luvio/jwt-manager": "5.44.0",
53
53
  "@luvio/network-adapter-composable": "0.158.7",
54
54
  "@luvio/network-adapter-fetch": "0.158.7",
55
- "@luvio/service-aura-network": "5.43.1",
56
- "@luvio/service-cache": "5.43.1",
57
- "@luvio/service-cache-control": "5.43.1",
58
- "@luvio/service-cache-inclusion-policy": "5.43.1",
59
- "@luvio/service-fetch-network": "5.43.1",
60
- "@luvio/service-instrument-command": "5.43.1",
61
- "@luvio/service-pubsub": "5.43.1",
62
- "@luvio/service-store": "5.43.1",
63
- "@luvio/utils": "5.43.1",
64
- "@salesforce/lds-adapters-uiapi-lex": "^1.369.0"
55
+ "@luvio/service-aura-network": "5.44.0",
56
+ "@luvio/service-cache": "5.44.0",
57
+ "@luvio/service-cache-control": "5.44.0",
58
+ "@luvio/service-cache-inclusion-policy": "5.44.0",
59
+ "@luvio/service-fetch-network": "5.44.0",
60
+ "@luvio/service-instrument-command": "5.44.0",
61
+ "@luvio/service-pubsub": "5.44.0",
62
+ "@luvio/service-store": "5.44.0",
63
+ "@luvio/utils": "5.44.0",
64
+ "@salesforce/lds-adapters-uiapi-lex": "^1.371.0"
65
65
  },
66
66
  "luvioBundlesize": [
67
67
  {