@lwrjs/core 0.15.0-alpha.3 → 0.15.0-alpha.30
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/build/cjs/__mocks__/undici.cjs +25 -0
- package/build/cjs/context/provider.cjs +4 -2
- package/build/cjs/index.cjs +2 -2
- package/build/cjs/middleware/bundle-middleware.cjs +1 -1
- package/build/cjs/middleware/request-processor-middleware.cjs +20 -3
- package/build/cjs/middleware/view-middleware.cjs +39 -6
- package/build/cjs/tools/static-generation.cjs +4 -4
- package/build/es/context/provider.js +2 -1
- package/build/es/index.js +2 -2
- package/build/es/middleware/bundle-middleware.js +3 -1
- package/build/es/middleware/request-processor-middleware.js +28 -5
- package/build/es/middleware/view-middleware.js +45 -6
- package/build/es/tools/static-generation.js +4 -4
- package/package.json +35 -35
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, {get: all[name], enumerable: true});
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// packages/@lwrjs/core/src/__mocks__/undici.ts
|
|
9
|
+
__markAsModule(exports);
|
|
10
|
+
__export(exports, {
|
|
11
|
+
Pool: () => Pool
|
|
12
|
+
});
|
|
13
|
+
var Pool = class {
|
|
14
|
+
async request() {
|
|
15
|
+
return Promise.resolve({
|
|
16
|
+
statusCode: 200,
|
|
17
|
+
body: {
|
|
18
|
+
text: () => Promise.resolve('{"one":1}'),
|
|
19
|
+
json: () => Promise.resolve({one: 1})
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
close() {
|
|
24
|
+
}
|
|
25
|
+
};
|
|
@@ -46,7 +46,8 @@ function createProviderContext(serverContext) {
|
|
|
46
46
|
environment,
|
|
47
47
|
basePath,
|
|
48
48
|
bundleConfig,
|
|
49
|
-
staticSiteGenerator
|
|
49
|
+
staticSiteGenerator,
|
|
50
|
+
_isSsrCompilerEnabled
|
|
50
51
|
} = serverContext.appConfig;
|
|
51
52
|
const {onModuleDefinitionChange, onModuleSourceChange} = serverContext.appObserver;
|
|
52
53
|
const {
|
|
@@ -84,7 +85,8 @@ function createProviderContext(serverContext) {
|
|
|
84
85
|
amdLoader,
|
|
85
86
|
esmLoader,
|
|
86
87
|
environment,
|
|
87
|
-
bundleConfig
|
|
88
|
+
bundleConfig,
|
|
89
|
+
_isSsrCompilerEnabled
|
|
88
90
|
}),
|
|
89
91
|
runtimeEnvironment: (0, import_shared_utils.deepFreeze)(serverContext.runtimeEnvironment),
|
|
90
92
|
watcherFactory: serverContext.watcherFactory,
|
package/build/cjs/index.cjs
CHANGED
|
@@ -109,9 +109,9 @@ var LwrApp = class {
|
|
|
109
109
|
this.config = appConfig;
|
|
110
110
|
this.runtimeEnvironment = runtimeEnvironment;
|
|
111
111
|
this.globalData = globalData;
|
|
112
|
-
const {basePath, serverType} = this.config;
|
|
112
|
+
const {basePath, serverType, caseSensitiveRoutes} = this.config;
|
|
113
113
|
this.serverType = serverType;
|
|
114
|
-
this.app = (0, import_server.createInternalServer)(serverType, {basePath});
|
|
114
|
+
this.app = (0, import_server.createInternalServer)(serverType, {basePath, caseSensitiveRoutes});
|
|
115
115
|
this.server = this.app.createHttpServer();
|
|
116
116
|
this.use = this.app.use.bind(this.app);
|
|
117
117
|
this.all = this.app.all.bind(this.app);
|
|
@@ -84,7 +84,7 @@ function createBundleMiddleware(context) {
|
|
|
84
84
|
if (signature !== import_shared_utils.LATEST_SIGNATURE) {
|
|
85
85
|
res.setHeader("Cache-control", "public, max-age=31536000, immutable");
|
|
86
86
|
}
|
|
87
|
-
res.status(200).type("application/javascript").send(bundleDefinition.
|
|
87
|
+
res.status(200).type("application/javascript").send(await bundleDefinition.getCode());
|
|
88
88
|
};
|
|
89
89
|
}
|
|
90
90
|
function createSourceMapMiddleware(context) {
|
|
@@ -45,7 +45,7 @@ function requestProcessorMiddleware(app, context) {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
requestClass = req.headers[MRT_REQUEST_CLASS_KEY];
|
|
48
|
-
requestDepth = (0, import_shared_utils.
|
|
48
|
+
requestDepth = (0, import_shared_utils.parseRequestDepth)(req.headers, req.query);
|
|
49
49
|
const forwarded = req.headers["forwarded"];
|
|
50
50
|
const host = req.headers["host"];
|
|
51
51
|
const forwardedProto = req.headers["x-forwarded-proto"];
|
|
@@ -57,14 +57,14 @@ function requestProcessorMiddleware(app, context) {
|
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
if (requestDepth && requestDepth >
|
|
60
|
+
if (requestDepth && requestDepth > 1) {
|
|
61
61
|
import_diagnostics.logger.error({
|
|
62
62
|
label: "request-processor-middleware",
|
|
63
63
|
message: `Lambda SSR request cycle detected: ${req.originalUrl}`
|
|
64
64
|
});
|
|
65
65
|
return res.status(400).send("Request depth limit reached");
|
|
66
66
|
}
|
|
67
|
-
if (req.headers && typeof requestClass === "string") {
|
|
67
|
+
if (req.headers && requestClass && typeof requestClass === "string") {
|
|
68
68
|
const parsedRequestClass = parseRequestClass(requestClass);
|
|
69
69
|
import_diagnostics.logger.debug({
|
|
70
70
|
label: `request-processor-middleware`,
|
|
@@ -72,6 +72,20 @@ function requestProcessorMiddleware(app, context) {
|
|
|
72
72
|
});
|
|
73
73
|
const pathValue = parsedRequestClass?.basePath || basePath || "";
|
|
74
74
|
req.basePath = pathValue === "" || pathValue.indexOf("/") === 0 ? pathValue : `/${pathValue}`;
|
|
75
|
+
const expressRequest = req.req;
|
|
76
|
+
if (expressRequest?.url && parsedRequestClass?.basePath) {
|
|
77
|
+
const {pathname, search} = new URL(expressRequest.url, "http://localhost");
|
|
78
|
+
if (pathname.startsWith(parsedRequestClass.basePath)) {
|
|
79
|
+
const newPath = pathname.slice(parsedRequestClass.basePath.length) || "/";
|
|
80
|
+
expressRequest.url = newPath + search;
|
|
81
|
+
expressRequest.originalUrl = newPath + search;
|
|
82
|
+
} else {
|
|
83
|
+
import_diagnostics.logger.warn({
|
|
84
|
+
label: `request-processor-middleware`,
|
|
85
|
+
message: `The URL requested for doesn't start with the Base path`
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
}
|
|
75
89
|
} else {
|
|
76
90
|
import_diagnostics.logger.debug({
|
|
77
91
|
label: `request-processor-middleware`,
|
|
@@ -83,6 +97,9 @@ function requestProcessorMiddleware(app, context) {
|
|
|
83
97
|
});
|
|
84
98
|
}
|
|
85
99
|
function parseRequestClass(requestClass) {
|
|
100
|
+
if (!requestClass) {
|
|
101
|
+
return {};
|
|
102
|
+
}
|
|
86
103
|
const keyValuePairs = requestClass.split(";");
|
|
87
104
|
const parsed = {};
|
|
88
105
|
for (const pair of keyValuePairs) {
|
|
@@ -32,6 +32,7 @@ var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
|
32
32
|
var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
|
|
33
33
|
var import_error_handling = __toModule(require("./utils/error-handling.cjs"));
|
|
34
34
|
var import_view_registry = __toModule(require("@lwrjs/view-registry"));
|
|
35
|
+
var import_instrumentation2 = __toModule(require("@lwrjs/instrumentation"));
|
|
35
36
|
function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
36
37
|
const errorRoute = errorRoutes.find((route2) => route2.status === 500);
|
|
37
38
|
const appConfig = context.appConfig;
|
|
@@ -61,7 +62,10 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
61
62
|
...defaultRuntimeParams,
|
|
62
63
|
url: viewRequest.url,
|
|
63
64
|
params: viewRequest.params,
|
|
64
|
-
query: viewRequest.query
|
|
65
|
+
query: viewRequest.query,
|
|
66
|
+
cookie: req.headers?.cookie,
|
|
67
|
+
trueClientIP: req.headers && req.headers["True-Client-IP"],
|
|
68
|
+
coreProxy: req.getCoreProxy(appConfig.coreProxy ?? void 0, route.bootstrap?.proxyForSSR)
|
|
65
69
|
};
|
|
66
70
|
const resolve = req.isJsonRequest() ? viewHandler.getViewJson : viewHandler.getViewContent;
|
|
67
71
|
let viewResponse;
|
|
@@ -97,6 +101,14 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
97
101
|
return resolve.call(viewHandler, viewRequest, errorRoute, runtimeEnvironment, runtimeParams);
|
|
98
102
|
});
|
|
99
103
|
resolvedRoute = errorRoute;
|
|
104
|
+
} finally {
|
|
105
|
+
if (traceId?.length) {
|
|
106
|
+
res.setHeader("x-trace-id", traceId);
|
|
107
|
+
res.set({
|
|
108
|
+
"Server-Timing": (0, import_instrumentation2.getTraceCollector)().getSpansInTrace(traceId)
|
|
109
|
+
});
|
|
110
|
+
(0, import_instrumentation2.getTraceCollector)().dropTrace(traceId);
|
|
111
|
+
}
|
|
100
112
|
}
|
|
101
113
|
if (req.isSiteGeneration()) {
|
|
102
114
|
res.setSiteGenerationMetadata(viewResponse.metadata);
|
|
@@ -111,10 +123,20 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
111
123
|
res.setHeader("cache-control", `public, max-age=${cacheTtl}`);
|
|
112
124
|
}
|
|
113
125
|
}
|
|
114
|
-
|
|
115
|
-
|
|
126
|
+
let status = resolvedRoute.status || viewResponse.status || 200;
|
|
127
|
+
const redirect = viewResponse.metadata?.viewDefinition?.redirect;
|
|
128
|
+
if (viewResponse.status === 301 || viewResponse.status === 302) {
|
|
129
|
+
status = viewResponse.status;
|
|
130
|
+
} else if (redirect) {
|
|
131
|
+
if ((0, import_shared_utils.isURL)(redirect.location) || redirect.location.startsWith("/")) {
|
|
132
|
+
status = redirect.status || 302;
|
|
133
|
+
res.set({
|
|
134
|
+
Location: addRedirectQueryParam(redirect.location, (0, import_shared_utils.parseRequestDepth)(req.headers, req.query))
|
|
135
|
+
});
|
|
136
|
+
} else {
|
|
137
|
+
import_diagnostics.logger.warn(`[view-middleware] Redirect failed because the URL is invalid: "${redirect.location}"`);
|
|
138
|
+
}
|
|
116
139
|
}
|
|
117
|
-
const status = resolvedRoute.status || viewResponse.status || 200;
|
|
118
140
|
res.status(status);
|
|
119
141
|
res.send(viewResponse.body);
|
|
120
142
|
};
|
|
@@ -199,7 +221,7 @@ function viewMiddleware(app, context) {
|
|
|
199
221
|
const localizedPath = `/:locale(${supportedStr})${routePath}`;
|
|
200
222
|
paths.push(localizedPath);
|
|
201
223
|
});
|
|
202
|
-
addDefaultLocaleRedirects(i18n.defaultLocale, defaultLocalePaths, app);
|
|
224
|
+
addDefaultLocaleRedirects(i18n.defaultLocale, defaultLocalePaths, i18n.defaultRedirectParams, app);
|
|
203
225
|
}
|
|
204
226
|
}
|
|
205
227
|
import_diagnostics.logger.debug({label: `view-middleware`, message: `Add view paths ${paths}`});
|
|
@@ -208,14 +230,25 @@ function viewMiddleware(app, context) {
|
|
|
208
230
|
app.get((0, import_shared_utils.getClientBootstrapConfigurationRoutes)(), (0, import_error_handling.handleErrors)(createConfigMiddleware(routes, context, viewHandler)));
|
|
209
231
|
app.get("/" + app.getRegexWildcard(), (0, import_error_handling.handleErrors)(createNotFoundMiddleware(errorRoutes, context, viewHandler)));
|
|
210
232
|
}
|
|
211
|
-
function addDefaultLocaleRedirects(defaultLocale, defaultLocalePaths, app) {
|
|
233
|
+
function addDefaultLocaleRedirects(defaultLocale, defaultLocalePaths, defaultRedirectParams, app) {
|
|
212
234
|
import_diagnostics.logger.debug({label: `view-middleware`, message: `Add default localized paths ${defaultLocalePaths}`});
|
|
213
235
|
app.get(defaultLocalePaths, (req, res) => {
|
|
214
236
|
let modifiedPath = req.originalUrl.replace(`/${defaultLocale}`, "");
|
|
215
237
|
if (modifiedPath.indexOf("/") !== 0) {
|
|
216
238
|
modifiedPath = `/${modifiedPath}`;
|
|
217
239
|
}
|
|
240
|
+
if (defaultRedirectParams) {
|
|
241
|
+
Object.entries(defaultRedirectParams).forEach(([key, value]) => {
|
|
242
|
+
modifiedPath += `${modifiedPath.includes("?") ? "&" : "?"}${key}=${value}`;
|
|
243
|
+
});
|
|
244
|
+
}
|
|
218
245
|
res.setHeader("Location", modifiedPath);
|
|
219
246
|
return res.sendStatus(301);
|
|
220
247
|
});
|
|
221
248
|
}
|
|
249
|
+
function addRedirectQueryParam(redirectUrl, depth) {
|
|
250
|
+
const fakeOrigin = "http://parse.com";
|
|
251
|
+
const url = (0, import_shared_utils.isURL)(redirectUrl) ? new URL(redirectUrl) : new URL(`${fakeOrigin}${redirectUrl}`);
|
|
252
|
+
url.searchParams.set(import_shared_utils.REQUEST_DEPTH_KEY, String(depth + 1));
|
|
253
|
+
return url.toString().replace(fakeOrigin, "");
|
|
254
|
+
}
|
|
@@ -232,12 +232,12 @@ var SiteGenerator = class {
|
|
|
232
232
|
addBundleToSiteMetadata(bundleDefinition, url, siteConfig) {
|
|
233
233
|
if (siteConfig.siteMetadata) {
|
|
234
234
|
const locale = siteConfig.locale;
|
|
235
|
-
const specifier = (0, import_site_metadata.getSiteBundleId)(bundleDefinition, locale, siteConfig.i18n);
|
|
236
|
-
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => (0, import_site_metadata.getSiteBundleId)(moduleRef, locale, siteConfig.i18n)) || [];
|
|
237
|
-
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => (0, import_site_metadata.getSiteBundleId)(moduleRef, locale, siteConfig.i18n));
|
|
235
|
+
const specifier = (0, import_site_metadata.getSiteBundleId)(bundleDefinition, locale, false, siteConfig.i18n);
|
|
236
|
+
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => (0, import_site_metadata.getSiteBundleId)(moduleRef, locale, false, siteConfig.i18n)) || [];
|
|
237
|
+
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => (0, import_site_metadata.getSiteBundleId)(moduleRef, locale, false, siteConfig.i18n));
|
|
238
238
|
const includedModules = bundleDefinition.bundleRecord.includedModules?.map((moduleRef) => {
|
|
239
239
|
const moduleId = (0, import_shared_utils.explodeSpecifier)(moduleRef);
|
|
240
|
-
return (0, import_site_metadata.getSiteBundleId)(moduleId, locale, siteConfig.i18n);
|
|
240
|
+
return (0, import_site_metadata.getSiteBundleId)(moduleId, locale, false, siteConfig.i18n);
|
|
241
241
|
}) || [];
|
|
242
242
|
const version = bundleDefinition.version === import_shared_utils.VERSION_NOT_PROVIDED ? void 0 : bundleDefinition.version;
|
|
243
243
|
const bundleMetadata = {
|
|
@@ -3,7 +3,7 @@ import { deepFreeze } from '@lwrjs/shared-utils';
|
|
|
3
3
|
import { SiteMetadataImpl } from '@lwrjs/static/site-metadata';
|
|
4
4
|
export function createProviderContext(serverContext) {
|
|
5
5
|
// This is a subset of config to user-land code
|
|
6
|
-
const { assets, cacheDir, i18n, lwc: { modules = [] }, routes, errorRoutes, rootDir, contentDir, layoutsDir, locker, amdLoader, esmLoader, environment, basePath, bundleConfig, staticSiteGenerator, } = serverContext.appConfig;
|
|
6
|
+
const { assets, cacheDir, i18n, lwc: { modules = [] }, routes, errorRoutes, rootDir, contentDir, layoutsDir, locker, amdLoader, esmLoader, environment, basePath, bundleConfig, staticSiteGenerator, _isSsrCompilerEnabled, } = serverContext.appConfig;
|
|
7
7
|
const { onModuleDefinitionChange, onModuleSourceChange } = serverContext.appObserver;
|
|
8
8
|
const { notifyModuleDefinitionChanged, notifyModuleSourceChanged, notifyViewSourceChanged, notifyAssetSourceChanged, } = serverContext.appEmitter;
|
|
9
9
|
const siteMetadata = staticSiteGenerator.outputDir && fs.existsSync(staticSiteGenerator.outputDir)
|
|
@@ -38,6 +38,7 @@ export function createProviderContext(serverContext) {
|
|
|
38
38
|
esmLoader,
|
|
39
39
|
environment,
|
|
40
40
|
bundleConfig,
|
|
41
|
+
_isSsrCompilerEnabled,
|
|
41
42
|
}),
|
|
42
43
|
runtimeEnvironment: deepFreeze(serverContext.runtimeEnvironment),
|
|
43
44
|
watcherFactory: serverContext.watcherFactory,
|
package/build/es/index.js
CHANGED
|
@@ -98,9 +98,9 @@ export class LwrApp {
|
|
|
98
98
|
this.config = appConfig;
|
|
99
99
|
this.runtimeEnvironment = runtimeEnvironment;
|
|
100
100
|
this.globalData = globalData;
|
|
101
|
-
const { basePath, serverType } = this.config;
|
|
101
|
+
const { basePath, serverType, caseSensitiveRoutes } = this.config;
|
|
102
102
|
this.serverType = serverType;
|
|
103
|
-
this.app = createInternalServer(serverType, { basePath });
|
|
103
|
+
this.app = createInternalServer(serverType, { basePath, caseSensitiveRoutes });
|
|
104
104
|
this.server = this.app.createHttpServer();
|
|
105
105
|
this.use = this.app.use.bind(this.app);
|
|
106
106
|
this.all = this.app.all.bind(this.app);
|
|
@@ -56,7 +56,9 @@ function createBundleMiddleware(context) {
|
|
|
56
56
|
if (signature !== LATEST_SIGNATURE) {
|
|
57
57
|
res.setHeader('Cache-control', 'public, max-age=31536000, immutable');
|
|
58
58
|
}
|
|
59
|
-
res.status(200)
|
|
59
|
+
res.status(200)
|
|
60
|
+
.type('application/javascript')
|
|
61
|
+
.send(await bundleDefinition.getCode());
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
64
|
function createSourceMapMiddleware(context) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
import { logger } from '@lwrjs/diagnostics';
|
|
10
|
-
import { REQUEST_DEPTH_HEADER, isLambdaEnv,
|
|
10
|
+
import { REQUEST_DEPTH_HEADER, isLambdaEnv, parseRequestDepth } from '@lwrjs/shared-utils';
|
|
11
11
|
const MRT_REQUEST_CLASS = 'X-Mobify-Request-Class';
|
|
12
12
|
const MRT_REQUEST_CLASS_KEY = MRT_REQUEST_CLASS.toLowerCase();
|
|
13
13
|
export function requestProcessorMiddleware(app, context) {
|
|
@@ -27,7 +27,7 @@ export function requestProcessorMiddleware(app, context) {
|
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
requestClass = req.headers[MRT_REQUEST_CLASS_KEY];
|
|
30
|
-
requestDepth =
|
|
30
|
+
requestDepth = parseRequestDepth(req.headers, req.query);
|
|
31
31
|
const forwarded = req.headers['forwarded'];
|
|
32
32
|
const host = req.headers['host'];
|
|
33
33
|
const forwardedProto = req.headers['x-forwarded-proto'];
|
|
@@ -40,8 +40,7 @@ export function requestProcessorMiddleware(app, context) {
|
|
|
40
40
|
});
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
|
|
44
|
-
if (requestDepth && requestDepth > 0) {
|
|
43
|
+
if (requestDepth && requestDepth > 1) {
|
|
45
44
|
logger.error({
|
|
46
45
|
label: 'request-processor-middleware',
|
|
47
46
|
message: `Lambda SSR request cycle detected: ${req.originalUrl}`,
|
|
@@ -49,7 +48,7 @@ export function requestProcessorMiddleware(app, context) {
|
|
|
49
48
|
// Return 400 Too Many Requests status
|
|
50
49
|
return res.status(400).send('Request depth limit reached');
|
|
51
50
|
}
|
|
52
|
-
if (req.headers && typeof requestClass === 'string') {
|
|
51
|
+
if (req.headers && requestClass && typeof requestClass === 'string') {
|
|
53
52
|
const parsedRequestClass = parseRequestClass(requestClass);
|
|
54
53
|
logger.debug({
|
|
55
54
|
label: `request-processor-middleware`,
|
|
@@ -58,6 +57,26 @@ export function requestProcessorMiddleware(app, context) {
|
|
|
58
57
|
const pathValue = parsedRequestClass?.basePath || basePath || '';
|
|
59
58
|
// If base path is '' or starts with / leave it alone
|
|
60
59
|
req.basePath = pathValue === '' || pathValue.indexOf('/') === 0 ? pathValue : `/${pathValue}`;
|
|
60
|
+
const expressRequest = req.req;
|
|
61
|
+
// This section is code added for the 103 hints support. If CDN passes us a basePath in the header
|
|
62
|
+
// If the basePath is at the start of the URL we need to remove it so we can match the expected route.
|
|
63
|
+
if (expressRequest?.url && parsedRequestClass?.basePath) {
|
|
64
|
+
// Separate the path and the query param using dummy local host here since we do not use it
|
|
65
|
+
const { pathname, search } = new URL(expressRequest.url, 'http://localhost');
|
|
66
|
+
if (pathname.startsWith(parsedRequestClass.basePath)) {
|
|
67
|
+
// Remove the basePath from the pathname
|
|
68
|
+
const newPath = pathname.slice(parsedRequestClass.basePath.length) || '/';
|
|
69
|
+
// Reconstruct the URL with the modified path and original query string
|
|
70
|
+
expressRequest.url = newPath + search;
|
|
71
|
+
expressRequest.originalUrl = newPath + search;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
logger.warn({
|
|
75
|
+
label: `request-processor-middleware`,
|
|
76
|
+
message: `The URL requested for doesn't start with the Base path`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
61
80
|
}
|
|
62
81
|
else {
|
|
63
82
|
logger.debug({
|
|
@@ -71,6 +90,10 @@ export function requestProcessorMiddleware(app, context) {
|
|
|
71
90
|
});
|
|
72
91
|
}
|
|
73
92
|
function parseRequestClass(requestClass) {
|
|
93
|
+
// If there is no requestClass do not bother parsing
|
|
94
|
+
if (!requestClass) {
|
|
95
|
+
return {};
|
|
96
|
+
}
|
|
74
97
|
// Split the Forwarded header into individual key-value pairs
|
|
75
98
|
const keyValuePairs = requestClass.split(';');
|
|
76
99
|
// Create an object to store the parsed values
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { descriptions, logger } from '@lwrjs/diagnostics';
|
|
2
2
|
import { getClientRoutes } from '@lwrjs/router';
|
|
3
|
-
import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, shortestTtl, } from '@lwrjs/shared-utils';
|
|
3
|
+
import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, isURL, parseRequestDepth, REQUEST_DEPTH_KEY, shortestTtl, } from '@lwrjs/shared-utils';
|
|
4
4
|
import { RequestHandlerSpan, getTracer } from '@lwrjs/instrumentation';
|
|
5
5
|
import { handleErrors } from './utils/error-handling.js';
|
|
6
6
|
import { LwrViewHandler } from '@lwrjs/view-registry';
|
|
7
|
+
import { getTraceCollector } from '@lwrjs/instrumentation';
|
|
7
8
|
function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
8
9
|
const errorRoute = errorRoutes.find((route) => route.status === 500);
|
|
9
10
|
const appConfig = context.appConfig;
|
|
@@ -36,6 +37,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
36
37
|
url: viewRequest.url,
|
|
37
38
|
params: viewRequest.params,
|
|
38
39
|
query: viewRequest.query,
|
|
40
|
+
cookie: req.headers?.cookie,
|
|
41
|
+
trueClientIP: req.headers && req.headers['True-Client-IP'],
|
|
42
|
+
coreProxy: req.getCoreProxy(appConfig.coreProxy ?? undefined, route.bootstrap?.proxyForSSR),
|
|
39
43
|
};
|
|
40
44
|
const resolve = req.isJsonRequest() ? viewHandler.getViewJson : viewHandler.getViewContent;
|
|
41
45
|
let viewResponse;
|
|
@@ -74,6 +78,15 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
74
78
|
});
|
|
75
79
|
resolvedRoute = errorRoute;
|
|
76
80
|
}
|
|
81
|
+
finally {
|
|
82
|
+
if (traceId?.length) {
|
|
83
|
+
res.setHeader('x-trace-id', traceId);
|
|
84
|
+
res.set({
|
|
85
|
+
'Server-Timing': getTraceCollector().getSpansInTrace(traceId),
|
|
86
|
+
});
|
|
87
|
+
getTraceCollector().dropTrace(traceId);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
77
90
|
if (req.isSiteGeneration()) {
|
|
78
91
|
res.setSiteGenerationMetadata(viewResponse.metadata);
|
|
79
92
|
}
|
|
@@ -90,10 +103,23 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
90
103
|
res.setHeader('cache-control', `public, max-age=${cacheTtl}`);
|
|
91
104
|
}
|
|
92
105
|
}
|
|
93
|
-
|
|
94
|
-
|
|
106
|
+
let status = resolvedRoute.status || viewResponse.status || 200;
|
|
107
|
+
const redirect = viewResponse.metadata?.viewDefinition?.redirect;
|
|
108
|
+
if (viewResponse.status === 301 || viewResponse.status === 302) {
|
|
109
|
+
// route handle redirect status takes precedence
|
|
110
|
+
status = viewResponse.status;
|
|
111
|
+
}
|
|
112
|
+
else if (redirect) {
|
|
113
|
+
if (isURL(redirect.location) || redirect.location.startsWith('/')) {
|
|
114
|
+
status = redirect.status || 302;
|
|
115
|
+
res.set({
|
|
116
|
+
Location: addRedirectQueryParam(redirect.location, parseRequestDepth(req.headers, req.query)),
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
logger.warn(`[view-middleware] Redirect failed because the URL is invalid: "${redirect.location}"`);
|
|
121
|
+
}
|
|
95
122
|
}
|
|
96
|
-
const status = resolvedRoute.status || viewResponse.status || 200;
|
|
97
123
|
res.status(status);
|
|
98
124
|
res.send(viewResponse.body);
|
|
99
125
|
};
|
|
@@ -193,7 +219,7 @@ export function viewMiddleware(app, context) {
|
|
|
193
219
|
const localizedPath = `/:locale(${supportedStr})${routePath}`;
|
|
194
220
|
paths.push(localizedPath);
|
|
195
221
|
});
|
|
196
|
-
addDefaultLocaleRedirects(i18n.defaultLocale, defaultLocalePaths, app);
|
|
222
|
+
addDefaultLocaleRedirects(i18n.defaultLocale, defaultLocalePaths, i18n.defaultRedirectParams, app);
|
|
197
223
|
}
|
|
198
224
|
}
|
|
199
225
|
logger.debug({ label: `view-middleware`, message: `Add view paths ${paths}` });
|
|
@@ -208,7 +234,7 @@ export function viewMiddleware(app, context) {
|
|
|
208
234
|
/**
|
|
209
235
|
* Adds a 301 redirect if attempting to route with default locale as the path prefix
|
|
210
236
|
*/
|
|
211
|
-
function addDefaultLocaleRedirects(defaultLocale, defaultLocalePaths, app) {
|
|
237
|
+
function addDefaultLocaleRedirects(defaultLocale, defaultLocalePaths, defaultRedirectParams, app) {
|
|
212
238
|
logger.debug({ label: `view-middleware`, message: `Add default localized paths ${defaultLocalePaths}` });
|
|
213
239
|
app.get(defaultLocalePaths, (req, res) => {
|
|
214
240
|
// Get the original URL path and split it into segments
|
|
@@ -217,9 +243,22 @@ function addDefaultLocaleRedirects(defaultLocale, defaultLocalePaths, app) {
|
|
|
217
243
|
if (modifiedPath.indexOf('/') !== 0) {
|
|
218
244
|
modifiedPath = `/${modifiedPath}`;
|
|
219
245
|
}
|
|
246
|
+
if (defaultRedirectParams) {
|
|
247
|
+
Object.entries(defaultRedirectParams).forEach(([key, value]) => {
|
|
248
|
+
modifiedPath += `${modifiedPath.includes('?') ? '&' : '?'}${key}=${value}`;
|
|
249
|
+
});
|
|
250
|
+
}
|
|
220
251
|
// Perform a 301 redirect to the modified URL
|
|
221
252
|
res.setHeader('Location', modifiedPath);
|
|
222
253
|
return res.sendStatus(301);
|
|
223
254
|
});
|
|
224
255
|
}
|
|
256
|
+
function addRedirectQueryParam(redirectUrl, depth) {
|
|
257
|
+
// add a request depth query param to the URL
|
|
258
|
+
// the depth header cannot be used since headers cannot be added to a redirect
|
|
259
|
+
const fakeOrigin = 'http://parse.com';
|
|
260
|
+
const url = isURL(redirectUrl) ? new URL(redirectUrl) : new URL(`${fakeOrigin}${redirectUrl}`);
|
|
261
|
+
url.searchParams.set(REQUEST_DEPTH_KEY, String(depth + 1));
|
|
262
|
+
return url.toString().replace(fakeOrigin, '');
|
|
263
|
+
}
|
|
225
264
|
//# sourceMappingURL=view-middleware.js.map
|
|
@@ -299,12 +299,12 @@ export default class SiteGenerator {
|
|
|
299
299
|
addBundleToSiteMetadata(bundleDefinition, url, siteConfig) {
|
|
300
300
|
if (siteConfig.siteMetadata) {
|
|
301
301
|
const locale = siteConfig.locale;
|
|
302
|
-
const specifier = getSiteBundleId(bundleDefinition, locale, siteConfig.i18n);
|
|
303
|
-
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => getSiteBundleId(moduleRef, locale, siteConfig.i18n)) || [];
|
|
304
|
-
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => getSiteBundleId(moduleRef, locale, siteConfig.i18n));
|
|
302
|
+
const specifier = getSiteBundleId(bundleDefinition, locale, false, siteConfig.i18n);
|
|
303
|
+
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => getSiteBundleId(moduleRef, locale, false, siteConfig.i18n)) || [];
|
|
304
|
+
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => getSiteBundleId(moduleRef, locale, false, siteConfig.i18n));
|
|
305
305
|
const includedModules = bundleDefinition.bundleRecord.includedModules?.map((moduleRef) => {
|
|
306
306
|
const moduleId = explodeSpecifier(moduleRef);
|
|
307
|
-
return getSiteBundleId(moduleId, locale, siteConfig.i18n);
|
|
307
|
+
return getSiteBundleId(moduleId, locale, false, siteConfig.i18n);
|
|
308
308
|
}) || [];
|
|
309
309
|
const version = bundleDefinition.version === VERSION_NOT_PROVIDED ? undefined : bundleDefinition.version;
|
|
310
310
|
const bundleMetadata = {
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.15.0-alpha.
|
|
7
|
+
"version": "0.15.0-alpha.30",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -43,46 +43,46 @@
|
|
|
43
43
|
"build": "tsc -b"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@lwrjs/app-service": "0.15.0-alpha.
|
|
47
|
-
"@lwrjs/asset-registry": "0.15.0-alpha.
|
|
48
|
-
"@lwrjs/asset-transformer": "0.15.0-alpha.
|
|
49
|
-
"@lwrjs/base-view-provider": "0.15.0-alpha.
|
|
50
|
-
"@lwrjs/base-view-transformer": "0.15.0-alpha.
|
|
51
|
-
"@lwrjs/client-modules": "0.15.0-alpha.
|
|
52
|
-
"@lwrjs/config": "0.15.0-alpha.
|
|
53
|
-
"@lwrjs/diagnostics": "0.15.0-alpha.
|
|
54
|
-
"@lwrjs/esbuild": "0.15.0-alpha.
|
|
55
|
-
"@lwrjs/fs-asset-provider": "0.15.0-alpha.
|
|
56
|
-
"@lwrjs/fs-watch": "0.15.0-alpha.
|
|
57
|
-
"@lwrjs/html-view-provider": "0.15.0-alpha.
|
|
58
|
-
"@lwrjs/instrumentation": "0.15.0-alpha.
|
|
59
|
-
"@lwrjs/loader": "0.15.0-alpha.
|
|
60
|
-
"@lwrjs/lwc-module-provider": "0.15.0-alpha.
|
|
61
|
-
"@lwrjs/lwc-ssr": "0.15.0-alpha.
|
|
62
|
-
"@lwrjs/markdown-view-provider": "0.15.0-alpha.
|
|
63
|
-
"@lwrjs/module-bundler": "0.15.0-alpha.
|
|
64
|
-
"@lwrjs/module-registry": "0.15.0-alpha.
|
|
65
|
-
"@lwrjs/npm-module-provider": "0.15.0-alpha.
|
|
66
|
-
"@lwrjs/nunjucks-view-provider": "0.15.0-alpha.
|
|
67
|
-
"@lwrjs/o11y": "0.15.0-alpha.
|
|
68
|
-
"@lwrjs/resource-registry": "0.15.0-alpha.
|
|
69
|
-
"@lwrjs/router": "0.15.0-alpha.
|
|
70
|
-
"@lwrjs/server": "0.15.0-alpha.
|
|
71
|
-
"@lwrjs/shared-utils": "0.15.0-alpha.
|
|
72
|
-
"@lwrjs/static": "0.15.0-alpha.
|
|
73
|
-
"@lwrjs/view-registry": "0.15.0-alpha.
|
|
46
|
+
"@lwrjs/app-service": "0.15.0-alpha.30",
|
|
47
|
+
"@lwrjs/asset-registry": "0.15.0-alpha.30",
|
|
48
|
+
"@lwrjs/asset-transformer": "0.15.0-alpha.30",
|
|
49
|
+
"@lwrjs/base-view-provider": "0.15.0-alpha.30",
|
|
50
|
+
"@lwrjs/base-view-transformer": "0.15.0-alpha.30",
|
|
51
|
+
"@lwrjs/client-modules": "0.15.0-alpha.30",
|
|
52
|
+
"@lwrjs/config": "0.15.0-alpha.30",
|
|
53
|
+
"@lwrjs/diagnostics": "0.15.0-alpha.30",
|
|
54
|
+
"@lwrjs/esbuild": "0.15.0-alpha.30",
|
|
55
|
+
"@lwrjs/fs-asset-provider": "0.15.0-alpha.30",
|
|
56
|
+
"@lwrjs/fs-watch": "0.15.0-alpha.30",
|
|
57
|
+
"@lwrjs/html-view-provider": "0.15.0-alpha.30",
|
|
58
|
+
"@lwrjs/instrumentation": "0.15.0-alpha.30",
|
|
59
|
+
"@lwrjs/loader": "0.15.0-alpha.30",
|
|
60
|
+
"@lwrjs/lwc-module-provider": "0.15.0-alpha.30",
|
|
61
|
+
"@lwrjs/lwc-ssr": "0.15.0-alpha.30",
|
|
62
|
+
"@lwrjs/markdown-view-provider": "0.15.0-alpha.30",
|
|
63
|
+
"@lwrjs/module-bundler": "0.15.0-alpha.30",
|
|
64
|
+
"@lwrjs/module-registry": "0.15.0-alpha.30",
|
|
65
|
+
"@lwrjs/npm-module-provider": "0.15.0-alpha.30",
|
|
66
|
+
"@lwrjs/nunjucks-view-provider": "0.15.0-alpha.30",
|
|
67
|
+
"@lwrjs/o11y": "0.15.0-alpha.30",
|
|
68
|
+
"@lwrjs/resource-registry": "0.15.0-alpha.30",
|
|
69
|
+
"@lwrjs/router": "0.15.0-alpha.30",
|
|
70
|
+
"@lwrjs/server": "0.15.0-alpha.30",
|
|
71
|
+
"@lwrjs/shared-utils": "0.15.0-alpha.30",
|
|
72
|
+
"@lwrjs/static": "0.15.0-alpha.30",
|
|
73
|
+
"@lwrjs/view-registry": "0.15.0-alpha.30",
|
|
74
74
|
"chokidar": "^3.6.0",
|
|
75
75
|
"esbuild": "^0.9.7",
|
|
76
76
|
"fs-extra": "^11.2.0",
|
|
77
77
|
"path-to-regexp": "^6.2.2",
|
|
78
|
-
"qs": "^6.
|
|
79
|
-
"rollup": "^2.
|
|
78
|
+
"qs": "^6.13.0",
|
|
79
|
+
"rollup": "^2.79.2",
|
|
80
80
|
"ws": "^8.18.0"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@lwrjs/types": "0.15.0-alpha.
|
|
84
|
-
"@types/ws": "^8.5.
|
|
85
|
-
"memfs": "^4.
|
|
83
|
+
"@lwrjs/types": "0.15.0-alpha.30",
|
|
84
|
+
"@types/ws": "^8.5.12",
|
|
85
|
+
"memfs": "^4.13.0"
|
|
86
86
|
},
|
|
87
87
|
"peerDependencies": {
|
|
88
88
|
"lwc": ">= 2.x"
|
|
@@ -93,5 +93,5 @@
|
|
|
93
93
|
"volta": {
|
|
94
94
|
"extends": "../../../package.json"
|
|
95
95
|
},
|
|
96
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "b563560f1d3ccbb6d6bab8a8a5d7b6a8456b9c48"
|
|
97
97
|
}
|