@lwrjs/lwc-ssr 0.15.0-alpha.21 → 0.15.0-alpha.22

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.
@@ -74,11 +74,10 @@ var FetchController = class {
74
74
  this.noOpActivated = false;
75
75
  };
76
76
  this.setFetchRequestContext = (context) => {
77
- const {host, headers, requestDepth, basePath, coreProxy} = context;
77
+ const {host, headers, requestDepth, coreProxy} = context;
78
78
  this.host = host;
79
79
  this.headers = headers;
80
80
  this.requestDepth = requestDepth;
81
- this.basePath = basePath;
82
81
  this.coreProxy = coreProxy;
83
82
  };
84
83
  this.killSwitchActivated = false;
@@ -109,8 +108,8 @@ var FetchController = class {
109
108
  }
110
109
  createFetchEndowment(trace) {
111
110
  return (request, init) => {
112
- const {host = "", requestDepth = 1, basePath = "/", coreProxy} = this;
113
- const origin = coreProxy?.origin || host;
111
+ const {host = "", requestDepth = 1, coreProxy} = this;
112
+ const origin = coreProxy?.origin && coreProxy.origin.startsWith("http") ? coreProxy.origin : host;
114
113
  const {finalRequest, finalUrl} = this.getFinalRequest(request, origin);
115
114
  const finalInit = {
116
115
  ...init,
@@ -129,7 +128,7 @@ var FetchController = class {
129
128
  });
130
129
  return trace({name: import_instrumentation.ViewSpan.Fetch, attributes: {url: finalUrl, coreProxy: coreProxyStr}}, () => {
131
130
  if (coreProxy) {
132
- return this.fetchWithAgent(finalUrl, finalInit, basePath, coreProxy).catch((err) => {
131
+ return this.fetchWithAgent(finalUrl, finalInit, host, coreProxy).catch((err) => {
133
132
  const {finalRequest: cdnRequest, finalUrl: cdnUrl} = this.getFinalRequest(request, host);
134
133
  import_diagnostics.logger.warn(`Fetching data directly from Core failed, retrying through CDN: ${cdnUrl}`, err.message || err);
135
134
  return fetch(cdnRequest, finalInit);
@@ -157,9 +156,17 @@ var FetchController = class {
157
156
  }
158
157
  return {finalRequest, finalUrl};
159
158
  }
160
- async fetchWithAgent(url, init, basePath, coreProxy) {
161
- const {origin, host, servername, sitePath} = coreProxy;
162
- const urlParts = new URL(url);
159
+ async fetchWithAgent(url, init, forwardedHost, coreProxy) {
160
+ let {origin, servername} = coreProxy;
161
+ const host = coreProxy.host ?? forwardedHost.replace(/^https?:\/\//, "");
162
+ const ENHANCED_DOMAIN_TLD = ".site.com";
163
+ const MY_DOMAIN_TLD = ".salesforce.com";
164
+ if (forwardedHost.endsWith(ENHANCED_DOMAIN_TLD)) {
165
+ origin = forwardedHost.slice(0, -ENHANCED_DOMAIN_TLD.length) + MY_DOMAIN_TLD;
166
+ servername = origin;
167
+ } else if (origin.startsWith(".")) {
168
+ origin = forwardedHost + origin;
169
+ }
163
170
  let client = CORE_CLIENTS.get(origin);
164
171
  if (!client) {
165
172
  client = new import_undici.Pool(origin, {
@@ -168,11 +175,8 @@ var FetchController = class {
168
175
  });
169
176
  CORE_CLIENTS.set(origin, client);
170
177
  }
171
- let path = urlParts.pathname + urlParts.search;
172
- if (sitePath) {
173
- const hasBasePath = basePath !== "/" && path.startsWith(basePath);
174
- path = hasBasePath ? path.replace(basePath, sitePath) : `${sitePath === "/" ? "" : sitePath}${path}`;
175
- }
178
+ const urlParts = new URL(url);
179
+ const path = urlParts.pathname + urlParts.search;
176
180
  return client.request({
177
181
  ...init,
178
182
  method: init.method || "GET",
@@ -182,7 +186,7 @@ var FetchController = class {
182
186
  }).then((res) => {
183
187
  import_diagnostics.logger.info({
184
188
  label: `post ${import_instrumentation.ViewSpan.Fetch}`,
185
- message: `status: ${res.statusCode}, path: ${path}, basePath: ${basePath}, coreProxy: ${JSON.stringify(coreProxy)}`
189
+ message: `status: ${res.statusCode}, path: ${path}, coreProxy: ${JSON.stringify(coreProxy)}, request info: ${JSON.stringify({origin, host, servername})}`
186
190
  });
187
191
  return {
188
192
  ...res,
@@ -209,7 +209,6 @@ function createContext(LWR, runtimeParams, runtimeEnvironment) {
209
209
  const fetchController = new import_fetchController.FetchController(trace, {
210
210
  host: runtimeParams.host,
211
211
  requestDepth: runtimeParams.requestDepth,
212
- basePath: runtimeParams.basePath || runtimeEnvironment.basePath,
213
212
  coreProxy: runtimeParams.coreProxy
214
213
  });
215
214
  const context = {
@@ -95,7 +95,7 @@ var Renderer = class {
95
95
  bootstrapServiceEvaluationMap = bootstrapContext.bootstrapServiceEvaluationMap;
96
96
  loader = await loaderPromise;
97
97
  const fetchController = loader.getFetchController();
98
- this.resetFetchController(fetchController, runtimeParams, runtimeEnvironment, route);
98
+ this.resetFetchController(fetchController, runtimeParams, route);
99
99
  const engineServerSpecifier = (0, import_shared_utils.getSpecifier)({
100
100
  specifier: "@lwc/engine-server",
101
101
  version: route.bootstrap.lwcVersion
@@ -192,13 +192,15 @@ var Renderer = class {
192
192
  }
193
193
  }
194
194
  }
195
- resetFetchController(fetchController, runtimeParams, runtimeEnvironment, route) {
195
+ resetFetchController(fetchController, runtimeParams, route) {
196
196
  fetchController.disableFetchKillSwitch();
197
197
  fetchController.setFetchRequestContext({
198
198
  host: runtimeParams.host,
199
199
  requestDepth: runtimeParams.requestDepth,
200
- headers: route.bootstrap.includeCookiesForSSR ? {Cookie: runtimeParams.cookie} : void 0,
201
- basePath: runtimeParams.basePath || runtimeEnvironment.basePath,
200
+ headers: route.bootstrap.includeCookiesForSSR ? {
201
+ Cookie: runtimeParams.cookie,
202
+ "True-Client-IP": runtimeParams.trueClientIP
203
+ } : {"True-Client-IP": runtimeParams.trueClientIP},
202
204
  coreProxy: runtimeParams.coreProxy
203
205
  });
204
206
  }
@@ -118,7 +118,8 @@ function getLoaderConfig(bootstrapModule, config, runtimeParams, serverData) {
118
118
  function getServerBootstrapServices(route) {
119
119
  return route.bootstrap.services.reduce((acc, service) => {
120
120
  if (service.ssr === true) {
121
- acc.push(service.name);
121
+ const serviceId = (0, import_shared_utils.getSpecifier)({specifier: service.name, version: service.version});
122
+ acc.push(serviceId);
122
123
  }
123
124
  return acc;
124
125
  }, []);
@@ -5,7 +5,6 @@ export type FetchRequestContext = {
5
5
  host?: string;
6
6
  requestDepth?: number;
7
7
  headers?: HeadersInit | undefined;
8
- basePath?: string;
9
8
  coreProxy?: DirectToCoreProxy;
10
9
  };
11
10
  /**
@@ -24,7 +23,6 @@ export declare class FetchController {
24
23
  private headers;
25
24
  private host;
26
25
  private requestDepth;
27
- private basePath;
28
26
  private coreProxy;
29
27
  fetchEndowment: FetchFunction;
30
28
  constructor(trace: TraceFn<Response>, context: FetchRequestContext);
@@ -71,11 +71,10 @@ export class FetchController {
71
71
  this.noOpActivated = false;
72
72
  };
73
73
  this.setFetchRequestContext = (context) => {
74
- const { host, headers, requestDepth, basePath, coreProxy } = context;
74
+ const { host, headers, requestDepth, coreProxy } = context;
75
75
  this.host = host;
76
76
  this.headers = headers;
77
77
  this.requestDepth = requestDepth;
78
- this.basePath = basePath;
79
78
  this.coreProxy = coreProxy;
80
79
  };
81
80
  this.killSwitchActivated = false;
@@ -117,8 +116,8 @@ export class FetchController {
117
116
  }
118
117
  createFetchEndowment(trace) {
119
118
  return (request, init) => {
120
- const { host = '', requestDepth = 1, basePath = '/', coreProxy } = this;
121
- const origin = coreProxy?.origin || host; // The Direct-to-Core proxy origin takes precedence over the Forwarded host
119
+ const { host = '', requestDepth = 1, coreProxy } = this;
120
+ const origin = coreProxy?.origin && coreProxy.origin.startsWith('http') ? coreProxy.origin : host; // The Direct-to-Core proxy origin takes precedence over the Forwarded host
122
121
  const { finalRequest, finalUrl } = this.getFinalRequest(request, origin);
123
122
  const finalInit = {
124
123
  ...init,
@@ -142,7 +141,7 @@ export class FetchController {
142
141
  // if the caller throws the fetch error, then it will be surfaced in the PARENT traces:
143
142
  // lwr.view.ssr.fetch (this) > lwr.view.ssr > lwr.view.ssr.island > lwr.view.render > lwr.handle.view
144
143
  if (coreProxy) {
145
- return this.fetchWithAgent(finalUrl, finalInit, basePath, coreProxy).catch((err) => {
144
+ return this.fetchWithAgent(finalUrl, finalInit, host, coreProxy).catch((err) => {
146
145
  const { finalRequest: cdnRequest, finalUrl: cdnUrl } = this.getFinalRequest(request, host);
147
146
  logger.warn(`Fetching data directly from Core failed, retrying through CDN: ${cdnUrl}`, err.message || err);
148
147
  return fetch(cdnRequest, finalInit);
@@ -173,9 +172,22 @@ export class FetchController {
173
172
  }
174
173
  return { finalRequest, finalUrl };
175
174
  }
176
- async fetchWithAgent(url, init, basePath, coreProxy) {
177
- const { origin, host, servername, sitePath } = coreProxy;
178
- const urlParts = new URL(url);
175
+ async fetchWithAgent(url, init, forwardedHost, coreProxy) {
176
+ let { origin, servername } = coreProxy;
177
+ const host = coreProxy.host ?? forwardedHost.replace(/^https?:\/\//, '');
178
+ const ENHANCED_DOMAIN_TLD = '.site.com';
179
+ const MY_DOMAIN_TLD = '.salesforce.com';
180
+ if (forwardedHost.endsWith(ENHANCED_DOMAIN_TLD)) {
181
+ // use the Salesforce TLD by replacing the Site TLD
182
+ // caller must be an Enhanced Domain on Cloudflare
183
+ origin = forwardedHost.slice(0, -ENHANCED_DOMAIN_TLD.length) + MY_DOMAIN_TLD;
184
+ // do not use SNI with the Enhanced Domain route
185
+ servername = origin;
186
+ }
187
+ else if (origin.startsWith('.')) {
188
+ // use the CDN origin if the leading '.' is missing in the coreProxy origin
189
+ origin = forwardedHost + origin;
190
+ }
179
191
  let client = CORE_CLIENTS.get(origin);
180
192
  if (!client) {
181
193
  client = new ClientPool(origin, {
@@ -184,14 +196,8 @@ export class FetchController {
184
196
  });
185
197
  CORE_CLIENTS.set(origin, client);
186
198
  }
187
- let path = urlParts.pathname + urlParts.search;
188
- if (sitePath) {
189
- // replace the data API basePath with the Core sitePath prefix
190
- const hasBasePath = basePath !== '/' && path.startsWith(basePath);
191
- path = hasBasePath
192
- ? path.replace(basePath, sitePath)
193
- : `${sitePath === '/' ? '' : sitePath}${path}`;
194
- }
199
+ const urlParts = new URL(url);
200
+ const path = urlParts.pathname + urlParts.search;
195
201
  return client
196
202
  .request({
197
203
  ...init,
@@ -207,7 +213,7 @@ export class FetchController {
207
213
  .then((res) => {
208
214
  logger.info({
209
215
  label: `post ${ViewSpan.Fetch}`,
210
- message: `status: ${res.statusCode}, path: ${path}, basePath: ${basePath}, coreProxy: ${JSON.stringify(coreProxy)}`,
216
+ message: `status: ${res.statusCode}, path: ${path}, coreProxy: ${JSON.stringify(coreProxy)}, request info: ${JSON.stringify({ origin, host, servername })}`,
211
217
  });
212
218
  return {
213
219
  // convert the response to a fetch Response object
@@ -222,7 +222,6 @@ function createContext(LWR, runtimeParams, runtimeEnvironment) {
222
222
  const fetchController = new FetchController(trace, {
223
223
  host: runtimeParams.host,
224
224
  requestDepth: runtimeParams.requestDepth,
225
- basePath: runtimeParams.basePath || runtimeEnvironment.basePath,
226
225
  coreProxy: runtimeParams.coreProxy,
227
226
  });
228
227
  const context = {
@@ -109,7 +109,7 @@ export class Renderer {
109
109
  loader = await loaderPromise;
110
110
  // reset/init the fetch controller between page renders
111
111
  const fetchController = loader.getFetchController();
112
- this.resetFetchController(fetchController, runtimeParams, runtimeEnvironment, route);
112
+ this.resetFetchController(fetchController, runtimeParams, route);
113
113
  // load and alias the LWC server engine
114
114
  // this MUST be done first in case bootstrap services depend on LWC
115
115
  const engineServerSpecifier = getSpecifier({
@@ -239,16 +239,18 @@ export class Renderer {
239
239
  }
240
240
  }
241
241
  }
242
- resetFetchController(fetchController, runtimeParams, runtimeEnvironment, route) {
242
+ resetFetchController(fetchController, runtimeParams, route) {
243
243
  // Re-enable fetch that was disabled at the end of the previous page render via `enableFetchKillSwitch`
244
244
  fetchController.disableFetchKillSwitch();
245
245
  fetchController.setFetchRequestContext({
246
246
  host: runtimeParams.host,
247
247
  requestDepth: runtimeParams.requestDepth,
248
248
  headers: route.bootstrap.includeCookiesForSSR
249
- ? { Cookie: runtimeParams.cookie }
250
- : undefined,
251
- basePath: runtimeParams.basePath || runtimeEnvironment.basePath,
249
+ ? {
250
+ Cookie: runtimeParams.cookie,
251
+ 'True-Client-IP': runtimeParams.trueClientIP,
252
+ }
253
+ : { 'True-Client-IP': runtimeParams.trueClientIP },
252
254
  coreProxy: runtimeParams.coreProxy,
253
255
  });
254
256
  }
package/build/es/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { logger, stringifyError } from '@lwrjs/diagnostics';
2
- import { buildEnvironmentContext, getFeatureFlags, normalizeVersionToUri, isLambdaEnv, } from '@lwrjs/shared-utils';
2
+ import { buildEnvironmentContext, getFeatureFlags, normalizeVersionToUri, isLambdaEnv, getSpecifier, } from '@lwrjs/shared-utils';
3
3
  const DEFAULT_SSR_TIMEOUT = 5000; // 5 seconds, override with process.env.SSR_TIMEOUT
4
4
  export const SSR_PROPS_ATTR = 'data-lwr-props-id';
5
5
  export function getPropsId() {
@@ -95,7 +95,8 @@ export function getLoaderConfig(bootstrapModule, config, runtimeParams, serverDa
95
95
  export function getServerBootstrapServices(route) {
96
96
  return route.bootstrap.services.reduce((acc, service) => {
97
97
  if (service.ssr === true) {
98
- acc.push(service.name);
98
+ const serviceId = getSpecifier({ specifier: service.name, version: service.version });
99
+ acc.push(serviceId);
99
100
  }
100
101
  return acc;
101
102
  }, []);
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
7
- "version": "0.15.0-alpha.21",
7
+ "version": "0.15.0-alpha.22",
8
8
  "homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
9
9
  "repository": {
10
10
  "type": "git",
@@ -42,17 +42,17 @@
42
42
  "build/**/*.d.ts"
43
43
  ],
44
44
  "dependencies": {
45
- "@lwrjs/config": "0.15.0-alpha.21",
46
- "@lwrjs/diagnostics": "0.15.0-alpha.21",
47
- "@lwrjs/instrumentation": "0.15.0-alpha.21",
48
- "@lwrjs/loader": "0.15.0-alpha.21",
49
- "@lwrjs/shared-utils": "0.15.0-alpha.21",
45
+ "@lwrjs/config": "0.15.0-alpha.22",
46
+ "@lwrjs/diagnostics": "0.15.0-alpha.22",
47
+ "@lwrjs/instrumentation": "0.15.0-alpha.22",
48
+ "@lwrjs/loader": "0.15.0-alpha.22",
49
+ "@lwrjs/shared-utils": "0.15.0-alpha.22",
50
50
  "fs-extra": "^11.2.0",
51
51
  "lru-cache": "^10.4.3",
52
52
  "undici": "^6.19.8"
53
53
  },
54
54
  "devDependencies": {
55
- "@lwrjs/types": "0.15.0-alpha.21",
55
+ "@lwrjs/types": "0.15.0-alpha.22",
56
56
  "jest": "^26.6.3",
57
57
  "memfs": "^4.9.3",
58
58
  "ts-jest": "^26.5.6"
@@ -63,5 +63,5 @@
63
63
  "volta": {
64
64
  "extends": "../../../package.json"
65
65
  },
66
- "gitHead": "4c09ff654569ab490fc77f196d3230b31404940e"
66
+ "gitHead": "0c89221b041a09f05fe6463ad385941f0351dbbe"
67
67
  }