@lwrjs/core 0.12.0-alpha.2 → 0.12.0-alpha.20
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/context/provider.cjs +7 -2
- package/build/cjs/index.cjs +19 -25
- package/build/cjs/info/route-handler.cjs +149 -0
- package/build/cjs/middleware/asset-middleware.cjs +41 -28
- package/build/cjs/middleware/bundle-middleware.cjs +7 -1
- package/build/cjs/middleware/mapping-middleware.cjs +4 -1
- package/build/cjs/middleware/module-middleware.cjs +7 -1
- package/build/cjs/middleware/request-processor-middleware.cjs +15 -1
- package/build/cjs/middleware/utils/error-handling.cjs +1 -1
- package/build/cjs/middleware/utils/identity.cjs +1 -1
- package/build/cjs/middleware/view-middleware.cjs +8 -2
- package/build/es/context/provider.js +7 -1
- package/build/es/index.d.ts +12 -5
- package/build/es/index.js +21 -28
- package/build/es/info/route-handler.d.ts +3 -0
- package/build/es/info/route-handler.js +123 -0
- package/build/es/middleware/asset-middleware.js +60 -33
- package/build/es/middleware/bundle-middleware.js +7 -0
- package/build/es/middleware/mapping-middleware.js +3 -0
- package/build/es/middleware/module-middleware.js +7 -0
- package/build/es/middleware/request-processor-middleware.js +17 -1
- package/build/es/middleware/utils/error-handling.js +1 -1
- package/build/es/middleware/utils/identity.js +5 -1
- package/build/es/middleware/view-middleware.js +7 -1
- package/package.json +41 -35
|
@@ -26,7 +26,9 @@ __markAsModule(exports);
|
|
|
26
26
|
__export(exports, {
|
|
27
27
|
createProviderContext: () => createProviderContext
|
|
28
28
|
});
|
|
29
|
+
var import_fs = __toModule(require("fs"));
|
|
29
30
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
31
|
+
var import_site_metadata = __toModule(require("@lwrjs/static/site-metadata"));
|
|
30
32
|
function createProviderContext(serverContext) {
|
|
31
33
|
const {
|
|
32
34
|
assets,
|
|
@@ -43,7 +45,8 @@ function createProviderContext(serverContext) {
|
|
|
43
45
|
esmLoader,
|
|
44
46
|
environment,
|
|
45
47
|
basePath,
|
|
46
|
-
bundleConfig
|
|
48
|
+
bundleConfig,
|
|
49
|
+
staticSiteGenerator
|
|
47
50
|
} = serverContext.appConfig;
|
|
48
51
|
const {onModuleDefinitionChange, onModuleSourceChange} = serverContext.appObserver;
|
|
49
52
|
const {
|
|
@@ -52,6 +55,7 @@ function createProviderContext(serverContext) {
|
|
|
52
55
|
notifyViewSourceChanged,
|
|
53
56
|
notifyAssetSourceChanged
|
|
54
57
|
} = serverContext.appEmitter;
|
|
58
|
+
const siteMetadata = staticSiteGenerator.outputDir && import_fs.default.existsSync(staticSiteGenerator.outputDir) ? new import_site_metadata.SiteMetadataImpl({rootDir: staticSiteGenerator.outputDir}) : void 0;
|
|
55
59
|
return {
|
|
56
60
|
appObserver: (0, import_shared_utils.deepFreeze)({onModuleDefinitionChange, onModuleSourceChange}),
|
|
57
61
|
appEmitter: {
|
|
@@ -83,6 +87,7 @@ function createProviderContext(serverContext) {
|
|
|
83
87
|
bundleConfig
|
|
84
88
|
}),
|
|
85
89
|
runtimeEnvironment: (0, import_shared_utils.deepFreeze)(serverContext.runtimeEnvironment),
|
|
86
|
-
watcherFactory: serverContext.watcherFactory
|
|
90
|
+
watcherFactory: serverContext.watcherFactory,
|
|
91
|
+
siteMetadata
|
|
87
92
|
};
|
|
88
93
|
}
|
package/build/cjs/index.cjs
CHANGED
|
@@ -70,10 +70,15 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
70
70
|
const skipValidation = true;
|
|
71
71
|
await (0, import_config.executeConfigHooks)(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
|
|
72
72
|
(0, import_config.executeInstrumentationHooks)(hooks);
|
|
73
|
-
(0, import_config.executeStartHooks)(hooks, appConfig, runtimeEnvironment);
|
|
74
73
|
}
|
|
75
74
|
const services = await (0, import_modules.loadServices)(appConfig);
|
|
76
75
|
const serverContext = (0, import_instrumentation.getTracer)().trace({name: import_instrumentation.CoreSpan.CreateServerContext}, () => (0, import_server2.createServerContext)(appConfig, runtimeEnvironment, globalData));
|
|
76
|
+
const routeHandlers = await (0, import_modules.loadRouteHandlers)(appConfig);
|
|
77
|
+
serverContext.routeHandlers = routeHandlers;
|
|
78
|
+
if (hooks.length) {
|
|
79
|
+
await (0, import_config.executeContextHooks)(hooks, serverContext);
|
|
80
|
+
(0, import_config.executeStartHooks)(hooks, appConfig, runtimeEnvironment);
|
|
81
|
+
}
|
|
77
82
|
const providerContext = (0, import_provider.createProviderContext)(serverContext);
|
|
78
83
|
const {moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler} = serverContext;
|
|
79
84
|
const moduleProviders = createServices(services.moduleProviders, providerContext);
|
|
@@ -94,29 +99,26 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
94
99
|
viewRegistry.addViewProviders(viewProviders);
|
|
95
100
|
viewRegistry.addViewTransformers(viewTransformers);
|
|
96
101
|
await serverContext.viewRegistry.initializeViewProviders();
|
|
97
|
-
const routeHandlers = await (0, import_modules.loadRouteHandlers)(appConfig);
|
|
98
|
-
serverContext.routeHandlers = routeHandlers;
|
|
99
102
|
return serverContext;
|
|
100
103
|
}
|
|
101
104
|
var LwrApp = class {
|
|
102
|
-
constructor(
|
|
105
|
+
constructor(configs) {
|
|
103
106
|
this.initialized = false;
|
|
104
107
|
const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.CreateServer});
|
|
105
|
-
const {appConfig, runtimeEnvironment, globalData} =
|
|
108
|
+
const {appConfig, runtimeEnvironment, globalData} = configs;
|
|
106
109
|
this.config = appConfig;
|
|
107
110
|
this.runtimeEnvironment = runtimeEnvironment;
|
|
108
111
|
this.globalData = globalData;
|
|
109
|
-
const {basePath} = this.config;
|
|
110
|
-
this.
|
|
112
|
+
const {basePath, serverType} = this.config;
|
|
113
|
+
this.serverType = serverType;
|
|
114
|
+
this.app = (0, import_server.createInternalServer)(serverType, {basePath});
|
|
111
115
|
this.server = this.app.createHttpServer();
|
|
116
|
+
this.use = this.app.use.bind(this.app);
|
|
117
|
+
this.all = this.app.all.bind(this.app);
|
|
118
|
+
this.get = this.app.get.bind(this.app);
|
|
119
|
+
this.post = this.app.post.bind(this.app);
|
|
112
120
|
span.end();
|
|
113
121
|
}
|
|
114
|
-
setConfig(config) {
|
|
115
|
-
const {appConfig, runtimeEnvironment, globalData} = (0, import_config.loadConfig)(config);
|
|
116
|
-
this.config = appConfig;
|
|
117
|
-
this.runtimeEnvironment = runtimeEnvironment;
|
|
118
|
-
this.globalData = globalData;
|
|
119
|
-
}
|
|
120
122
|
getConfig() {
|
|
121
123
|
return this.config;
|
|
122
124
|
}
|
|
@@ -168,24 +170,16 @@ var LwrApp = class {
|
|
|
168
170
|
});
|
|
169
171
|
});
|
|
170
172
|
}
|
|
171
|
-
|
|
172
|
-
this.server?.close &&
|
|
173
|
+
close() {
|
|
174
|
+
this.server?.close && this.server.close();
|
|
173
175
|
}
|
|
174
176
|
getInternalServer() {
|
|
175
177
|
return this.app.getImpl();
|
|
176
178
|
}
|
|
177
|
-
getServer() {
|
|
178
|
-
return {
|
|
179
|
-
use: this.app.use.bind(this.app),
|
|
180
|
-
all: this.app.all.bind(this.app),
|
|
181
|
-
get: this.app.get.bind(this.app),
|
|
182
|
-
post: this.app.post.bind(this.app),
|
|
183
|
-
getRegexWildcard: this.app.getRegexWildcard.bind(this.app)
|
|
184
|
-
};
|
|
185
|
-
}
|
|
186
179
|
};
|
|
187
180
|
function createServer(config) {
|
|
188
|
-
|
|
181
|
+
const configs = (0, import_config.loadConfig)(config);
|
|
182
|
+
return new LwrApp(configs);
|
|
189
183
|
}
|
|
190
184
|
async function generateStaticSite(config) {
|
|
191
185
|
config = config || {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __markAsModule = (target) => __defProp(target, "__esModule", {value: true});
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, {get: all[name], enumerable: true});
|
|
11
|
+
};
|
|
12
|
+
var __exportStar = (target, module2, desc) => {
|
|
13
|
+
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(module2))
|
|
15
|
+
if (!__hasOwnProp.call(target, key) && key !== "default")
|
|
16
|
+
__defProp(target, key, {get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable});
|
|
17
|
+
}
|
|
18
|
+
return target;
|
|
19
|
+
};
|
|
20
|
+
var __toModule = (module2) => {
|
|
21
|
+
return __exportStar(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? {get: () => module2.default, enumerable: true} : {value: module2, enumerable: true})), module2);
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// packages/@lwrjs/core/src/info/route-handler.ts
|
|
25
|
+
__markAsModule(exports);
|
|
26
|
+
__export(exports, {
|
|
27
|
+
default: () => siteInfoHandler
|
|
28
|
+
});
|
|
29
|
+
var import_config = __toModule(require("@lwrjs/config"));
|
|
30
|
+
var import_fs = __toModule(require("fs"));
|
|
31
|
+
var baseHtml = `<!DOCTYPE html>
|
|
32
|
+
<html lang="en">
|
|
33
|
+
<head>
|
|
34
|
+
<meta charset="utf-8" />
|
|
35
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
36
|
+
<title>Site Information</title>
|
|
37
|
+
<style>
|
|
38
|
+
body {
|
|
39
|
+
font-family: Arial, sans-serif;
|
|
40
|
+
margin: 0;
|
|
41
|
+
padding: 20px;
|
|
42
|
+
background-color: #f9f9f9;
|
|
43
|
+
color: #333;
|
|
44
|
+
display: flex;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.container {
|
|
48
|
+
max-width: 800px;
|
|
49
|
+
width: 100%;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
h1, h2 {
|
|
53
|
+
color: #555;
|
|
54
|
+
margin-bottom: 16px;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
ul {
|
|
58
|
+
list-style-type: none;
|
|
59
|
+
padding: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
li {
|
|
63
|
+
background-color: #fff;
|
|
64
|
+
border: 1px solid #ddd;
|
|
65
|
+
margin-bottom: 10px;
|
|
66
|
+
padding: 10px;
|
|
67
|
+
border-radius: 4px;
|
|
68
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
69
|
+
display: flex;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.key {
|
|
73
|
+
margin-right: 10px;
|
|
74
|
+
color: #777;
|
|
75
|
+
font-weight: normal;
|
|
76
|
+
min-width: 200px;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.val {
|
|
80
|
+
font-weight: bold;
|
|
81
|
+
color: steelblue;
|
|
82
|
+
font-size: 1.1em;
|
|
83
|
+
flex-grow: 1;
|
|
84
|
+
text-align: left;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.data-container {
|
|
88
|
+
padding: 20px;
|
|
89
|
+
border: 1px solid #333;
|
|
90
|
+
border-radius: 5px;
|
|
91
|
+
white-space: pre;
|
|
92
|
+
font-family: monospace;
|
|
93
|
+
text-align: justify;
|
|
94
|
+
};
|
|
95
|
+
</style>
|
|
96
|
+
</head>
|
|
97
|
+
<body>
|
|
98
|
+
<div class="container">
|
|
99
|
+
<h1>Site Information</h1>
|
|
100
|
+
<h2>Environment</h2>
|
|
101
|
+
{{ versionInfo }}
|
|
102
|
+
<h2>Metadata</h2>
|
|
103
|
+
{{ metadata }}
|
|
104
|
+
</div>
|
|
105
|
+
</body>
|
|
106
|
+
</html>
|
|
107
|
+
`;
|
|
108
|
+
async function siteInfoHandler(_request, context) {
|
|
109
|
+
const versionInfo = {
|
|
110
|
+
"LWR Version": import_config.LWR_VERSION,
|
|
111
|
+
"LWC Version": import_config.LWC_VERSION,
|
|
112
|
+
"Node Version": import_config.NODE_VERSION,
|
|
113
|
+
"PWA Kit Runtime Version": import_config.PWA_KIT_RUNTIME_VERSION
|
|
114
|
+
};
|
|
115
|
+
let versionInfoString = "<ul>";
|
|
116
|
+
for (const key in versionInfo) {
|
|
117
|
+
if (versionInfo[key] !== "note-provided") {
|
|
118
|
+
versionInfoString += `<li><span class="key">${key}:</span><span class="val">${versionInfo[key]}</span></li>
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
versionInfoString += "</ul>";
|
|
123
|
+
const providedMetadataPath = `${context.rootDir}/site/.metadata/runtime-info.json`;
|
|
124
|
+
let providedMetadata = {};
|
|
125
|
+
if (import_fs.default.existsSync(providedMetadataPath)) {
|
|
126
|
+
providedMetadata = JSON.parse(import_fs.default.readFileSync(providedMetadataPath, "utf-8"));
|
|
127
|
+
}
|
|
128
|
+
let providedInfoString = "<ul>";
|
|
129
|
+
for (const key in providedMetadata) {
|
|
130
|
+
if (providedMetadata[key] !== "note-provided") {
|
|
131
|
+
const value = typeof providedMetadata[key] === "object" ? `<div class="data-container val">${JSON.stringify(providedMetadata[key], null, 2)}</div>` : `<span class="val">${providedMetadata[key]}</span>`;
|
|
132
|
+
providedInfoString += `<li><span class="key">${key}:</span>${value}</li>
|
|
133
|
+
`;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
providedInfoString += "</ul>";
|
|
137
|
+
let infoHtml = baseHtml;
|
|
138
|
+
infoHtml = infoHtml.replace("{{ versionInfo }}", versionInfoString);
|
|
139
|
+
infoHtml = infoHtml.replace("{{ metadata }}", providedInfoString);
|
|
140
|
+
return {
|
|
141
|
+
body: infoHtml,
|
|
142
|
+
headers: {
|
|
143
|
+
"content-type": `text/html; charset=utf-8`
|
|
144
|
+
},
|
|
145
|
+
cache: {
|
|
146
|
+
ttl: "200s"
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
}
|
|
@@ -31,6 +31,24 @@ var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
|
31
31
|
var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
|
|
32
32
|
var import_identity = __toModule(require("./utils/identity.cjs"));
|
|
33
33
|
var import_error_handling = __toModule(require("./utils/error-handling.cjs"));
|
|
34
|
+
var import_fs_extra = __toModule(require("fs-extra"));
|
|
35
|
+
function assetMiddleware(app, context) {
|
|
36
|
+
const paths = context.appConfig.assets.map((config) => {
|
|
37
|
+
const assetDirConfig = config;
|
|
38
|
+
let urlPath = config.urlPath;
|
|
39
|
+
if (assetDirConfig.root) {
|
|
40
|
+
urlPath = "/:filename";
|
|
41
|
+
} else if (assetDirConfig.dir) {
|
|
42
|
+
urlPath += app.getRegexWildcard();
|
|
43
|
+
}
|
|
44
|
+
return urlPath;
|
|
45
|
+
});
|
|
46
|
+
app.get([
|
|
47
|
+
...[...new Set(paths)],
|
|
48
|
+
"/:apiVersion/:assetType(asset|content-asset)/:immutable?/s/:signature/" + app.getRegexWildcard(),
|
|
49
|
+
"/:apiVersion/:assetType(asset|content-asset)/:immutable?/" + app.getRegexWildcard()
|
|
50
|
+
], (0, import_error_handling.handleErrors)(createAssetMiddleware(context)));
|
|
51
|
+
}
|
|
34
52
|
function createAssetMiddleware(context) {
|
|
35
53
|
const {
|
|
36
54
|
assetRegistry,
|
|
@@ -43,23 +61,16 @@ function createAssetMiddleware(context) {
|
|
|
43
61
|
assetId.specifier = import_path.default.join(basePath, assetId.specifier);
|
|
44
62
|
}
|
|
45
63
|
try {
|
|
64
|
+
let asset;
|
|
46
65
|
const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
|
|
47
66
|
if (assetUri.external) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
52
|
-
res.sendStatus(302);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
const asset = await (0, import_instrumentation.getTracer)().trace({
|
|
56
|
-
name: import_instrumentation.RequestHandlerSpan.GetAsset,
|
|
57
|
-
attributes: {
|
|
58
|
-
specifier: assetId.specifier
|
|
67
|
+
asset = await getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment);
|
|
68
|
+
if (!import_fs_extra.default.existsSync(asset.entry) && assetUri.uri.startsWith("/mobify/bundle")) {
|
|
69
|
+
return sendRedirect(res, assetUri);
|
|
59
70
|
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
}
|
|
71
|
+
} else {
|
|
72
|
+
asset = await getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment);
|
|
73
|
+
}
|
|
63
74
|
if (req.isSiteGeneration()) {
|
|
64
75
|
res.setSiteGenerationMetadata({asset});
|
|
65
76
|
}
|
|
@@ -81,20 +92,22 @@ function createAssetMiddleware(context) {
|
|
|
81
92
|
}
|
|
82
93
|
};
|
|
83
94
|
}
|
|
84
|
-
function
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} else if (assetDirConfig.dir) {
|
|
91
|
-
urlPath += app.getRegexWildcard();
|
|
95
|
+
async function getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment) {
|
|
96
|
+
const asset = await (0, import_instrumentation.getTracer)().trace({
|
|
97
|
+
name: import_instrumentation.RequestHandlerSpan.GetAsset,
|
|
98
|
+
attributes: {
|
|
99
|
+
specifier: assetId.specifier,
|
|
100
|
+
url: req.originalUrl
|
|
92
101
|
}
|
|
93
|
-
|
|
102
|
+
}, () => {
|
|
103
|
+
return assetRegistry.getAsset({...assetId, signature}, runtimeEnvironment, req.isSiteGeneration());
|
|
94
104
|
});
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
105
|
+
return asset;
|
|
106
|
+
}
|
|
107
|
+
function sendRedirect(res, assetUri) {
|
|
108
|
+
res.set({
|
|
109
|
+
Location: assetUri.uri,
|
|
110
|
+
"cache-control": "public, max-age=60"
|
|
111
|
+
});
|
|
112
|
+
res.sendStatus(302);
|
|
100
113
|
}
|
|
@@ -53,6 +53,11 @@ function createBundleMiddleware(context) {
|
|
|
53
53
|
res.send(import_diagnostics.descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
54
54
|
return;
|
|
55
55
|
}
|
|
56
|
+
if (!req.validateApiVersion(appConfig)) {
|
|
57
|
+
res.status(400);
|
|
58
|
+
res.send(import_diagnostics.descriptions.UNRESOLVABLE.INVALID_API_VERSION(req.params.apiVersion, appConfig.apiVersion).message);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
56
61
|
const {runtimeEnvironment, runtimeParams} = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
57
62
|
const importer = req.query.importer ? await (0, import_request.getRequestImporter)(req, moduleRegistry, runtimeParams) : void 0;
|
|
58
63
|
const {moduleId, signature} = (0, import_identity.getModuleIdentity)(req, importer);
|
|
@@ -64,7 +69,8 @@ function createBundleMiddleware(context) {
|
|
|
64
69
|
const bundleDefinition = await (0, import_instrumentation.getTracer)().trace({
|
|
65
70
|
name: import_instrumentation.RequestHandlerSpan.GetBundle,
|
|
66
71
|
attributes: {
|
|
67
|
-
specifier: moduleId.specifier
|
|
72
|
+
specifier: moduleId.specifier,
|
|
73
|
+
url: req.originalUrl
|
|
68
74
|
}
|
|
69
75
|
}, () => {
|
|
70
76
|
return moduleBundler.getModuleBundle(moduleId, {...runtimeEnvironment, bundle: true, sourceMapUrl}, runtimeParams);
|
|
@@ -47,7 +47,10 @@ function createMappingMiddleware(context) {
|
|
|
47
47
|
const {runtimeEnvironment, runtimeParams} = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
48
48
|
const {moduleIds} = (0, import_identity.getMappingIdentity)(req);
|
|
49
49
|
const importMetadata = await (0, import_instrumentation.getTracer)().trace({
|
|
50
|
-
name: import_instrumentation.RequestHandlerSpan.GetMapping
|
|
50
|
+
name: import_instrumentation.RequestHandlerSpan.GetMapping,
|
|
51
|
+
attributes: {
|
|
52
|
+
url: req.originalUrl
|
|
53
|
+
}
|
|
51
54
|
}, () => {
|
|
52
55
|
return (0, import_shared_utils.getImportMetadataMappings)(moduleIds, runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler);
|
|
53
56
|
});
|
|
@@ -47,6 +47,11 @@ function createModuleMiddleware(context) {
|
|
|
47
47
|
res.send(import_diagnostics.descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
|
+
if (!req.validateApiVersion(appConfig)) {
|
|
51
|
+
res.status(400);
|
|
52
|
+
res.send(import_diagnostics.descriptions.UNRESOLVABLE.INVALID_API_VERSION(req.params.apiVersion, appConfig.apiVersion).message);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
50
55
|
const {runtimeEnvironment, runtimeParams} = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
51
56
|
const importer = req.query.importer ? await (0, import_request.getRequestImporter)(req, moduleRegistry, runtimeParams) : void 0;
|
|
52
57
|
const {moduleId, signature} = (0, import_identity.getModuleIdentity)(req, importer);
|
|
@@ -57,7 +62,8 @@ function createModuleMiddleware(context) {
|
|
|
57
62
|
const moduleDefinition = await (0, import_instrumentation.getTracer)().trace({
|
|
58
63
|
name: import_instrumentation.RequestHandlerSpan.GetModule,
|
|
59
64
|
attributes: {
|
|
60
|
-
specifier: moduleId.specifier
|
|
65
|
+
specifier: moduleId.specifier,
|
|
66
|
+
url: req.originalUrl
|
|
61
67
|
}
|
|
62
68
|
}, () => {
|
|
63
69
|
return moduleRegistry.getLinkedModule(moduleId, {...runtimeEnvironment, bundle: false}, runtimeParams);
|
|
@@ -27,14 +27,20 @@ __export(exports, {
|
|
|
27
27
|
requestProcessorMiddleware: () => requestProcessorMiddleware
|
|
28
28
|
});
|
|
29
29
|
var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
30
|
+
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
30
31
|
var MRT_REQUEST_CLASS = "X-Mobify-Request-Class";
|
|
31
32
|
var MRT_REQUEST_CLASS_KEY = MRT_REQUEST_CLASS.toLowerCase();
|
|
32
33
|
function requestProcessorMiddleware(app, context) {
|
|
33
34
|
const {basePath} = context.runtimeEnvironment;
|
|
34
|
-
app.use(async (req,
|
|
35
|
+
app.use(async (req, res, next) => {
|
|
35
36
|
let requestClass;
|
|
37
|
+
let requestDepth;
|
|
36
38
|
if (req.headers) {
|
|
37
39
|
if (import_diagnostics.logger.isDebugEnabled()) {
|
|
40
|
+
import_diagnostics.logger.debug({
|
|
41
|
+
label: `request-processor-middleware`,
|
|
42
|
+
message: `Request: ${req.originalUrl}`
|
|
43
|
+
});
|
|
38
44
|
for (const headerName in req.headers) {
|
|
39
45
|
import_diagnostics.logger.debug({
|
|
40
46
|
label: `request-processor-middleware`,
|
|
@@ -43,6 +49,14 @@ function requestProcessorMiddleware(app, context) {
|
|
|
43
49
|
}
|
|
44
50
|
}
|
|
45
51
|
requestClass = req.headers[MRT_REQUEST_CLASS_KEY];
|
|
52
|
+
requestDepth = (0, import_shared_utils.parseRequestDepthHeader)(req.headers);
|
|
53
|
+
}
|
|
54
|
+
if (requestDepth && requestDepth > 1) {
|
|
55
|
+
import_diagnostics.logger.warn({
|
|
56
|
+
label: "request-processor-middleware",
|
|
57
|
+
message: "Lambda SSR request cycle detected"
|
|
58
|
+
});
|
|
59
|
+
return res.status(400).send("Request depth limit reached");
|
|
46
60
|
}
|
|
47
61
|
if (req.headers && typeof requestClass === "string") {
|
|
48
62
|
const parsedRequestClass = parseRequestClass(requestClass);
|
|
@@ -35,7 +35,7 @@ function createReturnStatus(error, url) {
|
|
|
35
35
|
if (error instanceof import_diagnostics.LwrUnresolvableError) {
|
|
36
36
|
return {status: 404, message: error.message};
|
|
37
37
|
}
|
|
38
|
-
return {status: 500, message: import_diagnostics.descriptions.
|
|
38
|
+
return {status: 500, message: import_diagnostics.descriptions.SERVER.SERVER_ERROR(url).message};
|
|
39
39
|
}
|
|
40
40
|
function handleErrors(middleware) {
|
|
41
41
|
return async (req, res, next) => {
|
|
@@ -75,7 +75,7 @@ function getResourceIdentity(req) {
|
|
|
75
75
|
}
|
|
76
76
|
function getAssetIdentity(req) {
|
|
77
77
|
const {signature, immutable, assetType: type} = req.params;
|
|
78
|
-
const specifier = type ? "/" + req.params[0] : req.originalUrl.split("?")[0];
|
|
78
|
+
const specifier = type ? process.platform === "win32" ? req.params[0] : "/" + req.params[0] : req.originalUrl.split("?")[0];
|
|
79
79
|
if (validateSpecifier(specifier) === false) {
|
|
80
80
|
throw (0, import_diagnostics.createSingleDiagnosticError)({
|
|
81
81
|
description: import_diagnostics.descriptions.UNRESOLVABLE.INVALID_SPECIFIER(specifier)
|
|
@@ -66,13 +66,16 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
66
66
|
const resolve = req.isJsonRequest() ? viewHandler.getViewJson : viewHandler.getViewContent;
|
|
67
67
|
let viewResponse;
|
|
68
68
|
let resolvedRoute;
|
|
69
|
+
let traceId;
|
|
69
70
|
try {
|
|
70
71
|
viewResponse = await (0, import_instrumentation.getTracer)().trace({
|
|
71
72
|
name: import_instrumentation.RequestHandlerSpan.GetView,
|
|
72
73
|
attributes: {
|
|
73
|
-
view: route.id
|
|
74
|
+
view: route.id,
|
|
75
|
+
url: req.originalUrl
|
|
74
76
|
}
|
|
75
|
-
}, () => {
|
|
77
|
+
}, (span) => {
|
|
78
|
+
traceId = span.traceId;
|
|
76
79
|
return resolve.call(viewHandler, viewRequest, route, runtimeEnvironment, runtimeParams);
|
|
77
80
|
});
|
|
78
81
|
resolvedRoute = route;
|
|
@@ -105,6 +108,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
105
108
|
res.setHeader("cache-control", `public, max-age=${cacheTtl}`);
|
|
106
109
|
}
|
|
107
110
|
}
|
|
111
|
+
if (traceId?.length) {
|
|
112
|
+
res.setHeader("x-trace-id", traceId);
|
|
113
|
+
}
|
|
108
114
|
const status = resolvedRoute.status || viewResponse.status || 200;
|
|
109
115
|
res.status(status);
|
|
110
116
|
res.send(viewResponse.body);
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
1
2
|
import { deepFreeze } from '@lwrjs/shared-utils';
|
|
3
|
+
import { SiteMetadataImpl } from '@lwrjs/static/site-metadata';
|
|
2
4
|
export function createProviderContext(serverContext) {
|
|
3
5
|
// This is a subset of config to user-land code
|
|
4
|
-
const { assets, cacheDir, i18n, lwc: { modules = [] }, routes, errorRoutes, rootDir, contentDir, layoutsDir, locker, amdLoader, esmLoader, environment, basePath, bundleConfig, } = serverContext.appConfig;
|
|
6
|
+
const { assets, cacheDir, i18n, lwc: { modules = [] }, routes, errorRoutes, rootDir, contentDir, layoutsDir, locker, amdLoader, esmLoader, environment, basePath, bundleConfig, staticSiteGenerator, } = serverContext.appConfig;
|
|
5
7
|
const { onModuleDefinitionChange, onModuleSourceChange } = serverContext.appObserver;
|
|
6
8
|
const { notifyModuleDefinitionChanged, notifyModuleSourceChanged, notifyViewSourceChanged, notifyAssetSourceChanged, } = serverContext.appEmitter;
|
|
9
|
+
const siteMetadata = staticSiteGenerator.outputDir && fs.existsSync(staticSiteGenerator.outputDir)
|
|
10
|
+
? new SiteMetadataImpl({ rootDir: staticSiteGenerator.outputDir })
|
|
11
|
+
: undefined;
|
|
7
12
|
return {
|
|
8
13
|
appObserver: deepFreeze({ onModuleDefinitionChange, onModuleSourceChange }),
|
|
9
14
|
appEmitter: {
|
|
@@ -36,6 +41,7 @@ export function createProviderContext(serverContext) {
|
|
|
36
41
|
}),
|
|
37
42
|
runtimeEnvironment: deepFreeze(serverContext.runtimeEnvironment),
|
|
38
43
|
watcherFactory: serverContext.watcherFactory,
|
|
44
|
+
siteMetadata,
|
|
39
45
|
};
|
|
40
46
|
}
|
|
41
47
|
//# sourceMappingURL=provider.js.map
|
package/build/es/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { LwrGlobalConfig, NormalizedLwrGlobalConfig, ServerTypeImpl,
|
|
1
|
+
import type { LwrGlobalConfig, NormalizedLwrGlobalConfig, ServerTypeImpl, ServerTypes, RuntimeEnvironment, GlobalData, MiddlewareFunction } from '@lwrjs/types';
|
|
2
2
|
export declare class LwrApp {
|
|
3
3
|
private app;
|
|
4
4
|
private server;
|
|
@@ -6,8 +6,16 @@ export declare class LwrApp {
|
|
|
6
6
|
private config;
|
|
7
7
|
private runtimeEnvironment;
|
|
8
8
|
private globalData;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
serverType: ServerTypes;
|
|
10
|
+
use: (m: MiddlewareFunction) => void;
|
|
11
|
+
all: (path: string | string[], m: MiddlewareFunction) => void;
|
|
12
|
+
get: (path: string | string[], m: MiddlewareFunction) => void;
|
|
13
|
+
post: (path: string | string[], m: MiddlewareFunction) => void;
|
|
14
|
+
constructor(configs: {
|
|
15
|
+
appConfig: NormalizedLwrGlobalConfig;
|
|
16
|
+
runtimeEnvironment: RuntimeEnvironment;
|
|
17
|
+
globalData: GlobalData;
|
|
18
|
+
});
|
|
11
19
|
getConfig(): NormalizedLwrGlobalConfig;
|
|
12
20
|
init(): Promise<void>;
|
|
13
21
|
listen(callback?: ((opts: {
|
|
@@ -17,9 +25,8 @@ export declare class LwrApp {
|
|
|
17
25
|
serverMode: string;
|
|
18
26
|
port: number;
|
|
19
27
|
}>;
|
|
20
|
-
close():
|
|
28
|
+
close(): void;
|
|
21
29
|
getInternalServer<S extends ServerTypes>(): ServerTypeImpl<S>;
|
|
22
|
-
getServer(): PublicAppServer<ServerTypes>;
|
|
23
30
|
}
|
|
24
31
|
export declare function createServer(config?: LwrGlobalConfig): LwrApp;
|
|
25
32
|
export declare function generateStaticSite(config?: LwrGlobalConfig): Promise<NormalizedLwrGlobalConfig>;
|
package/build/es/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG } from '@lwrjs/shared-utils';
|
|
2
2
|
import { createInternalServer } from '@lwrjs/server';
|
|
3
3
|
import { LwrServerError, createSingleDiagnosticError, descriptions, logger } from '@lwrjs/diagnostics';
|
|
4
|
-
import { loadConfig, executeConfigHooks, executeStartHooks, executeInstrumentationHooks, } from '@lwrjs/config';
|
|
4
|
+
import { loadConfig, executeConfigHooks, executeStartHooks, executeInstrumentationHooks, executeContextHooks, } from '@lwrjs/config';
|
|
5
5
|
import { loadHooks, loadServices, loadRouteHandlers } from '@lwrjs/config/modules';
|
|
6
6
|
import SiteGenerator from './tools/static-generation.js';
|
|
7
7
|
import { warmupServer } from './tools/server-warmup.js';
|
|
@@ -47,12 +47,18 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
47
47
|
const skipValidation = true; // skip for config hook, since `executeStartHooks` hook will validate
|
|
48
48
|
await executeConfigHooks(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
|
|
49
49
|
executeInstrumentationHooks(hooks);
|
|
50
|
-
executeStartHooks(hooks, appConfig, runtimeEnvironment);
|
|
51
50
|
}
|
|
52
51
|
// load all configurable modules
|
|
53
52
|
const services = await loadServices(appConfig);
|
|
54
53
|
// create all framework components(ie. registries)
|
|
55
54
|
const serverContext = getTracer().trace({ name: CoreSpan.CreateServerContext }, () => createServerContext(appConfig, runtimeEnvironment, globalData));
|
|
55
|
+
// set routes on server context
|
|
56
|
+
const routeHandlers = await loadRouteHandlers(appConfig);
|
|
57
|
+
serverContext.routeHandlers = routeHandlers;
|
|
58
|
+
if (hooks.length) {
|
|
59
|
+
await executeContextHooks(hooks, serverContext);
|
|
60
|
+
executeStartHooks(hooks, appConfig, runtimeEnvironment);
|
|
61
|
+
}
|
|
56
62
|
// create public subset of configurations
|
|
57
63
|
const providerContext = createProviderContext(serverContext);
|
|
58
64
|
const { moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler } = serverContext;
|
|
@@ -82,30 +88,26 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
82
88
|
viewRegistry.addViewTransformers(viewTransformers);
|
|
83
89
|
// invoke async initialization
|
|
84
90
|
await serverContext.viewRegistry.initializeViewProviders();
|
|
85
|
-
// set routes on server context
|
|
86
|
-
const routeHandlers = await loadRouteHandlers(appConfig);
|
|
87
|
-
serverContext.routeHandlers = routeHandlers;
|
|
88
91
|
return serverContext;
|
|
89
92
|
}
|
|
90
93
|
export class LwrApp {
|
|
91
|
-
constructor(
|
|
94
|
+
constructor(configs) {
|
|
92
95
|
this.initialized = false;
|
|
93
96
|
const span = getTracer().startSpan({ name: CoreSpan.CreateServer });
|
|
94
|
-
const { appConfig, runtimeEnvironment, globalData } =
|
|
97
|
+
const { appConfig, runtimeEnvironment, globalData } = configs;
|
|
95
98
|
this.config = appConfig;
|
|
96
99
|
this.runtimeEnvironment = runtimeEnvironment;
|
|
97
100
|
this.globalData = globalData;
|
|
98
|
-
const { basePath } = this.config;
|
|
99
|
-
this.
|
|
101
|
+
const { basePath, serverType } = this.config;
|
|
102
|
+
this.serverType = serverType;
|
|
103
|
+
this.app = createInternalServer(serverType, { basePath });
|
|
100
104
|
this.server = this.app.createHttpServer();
|
|
105
|
+
this.use = this.app.use.bind(this.app);
|
|
106
|
+
this.all = this.app.all.bind(this.app);
|
|
107
|
+
this.get = this.app.get.bind(this.app);
|
|
108
|
+
this.post = this.app.post.bind(this.app);
|
|
101
109
|
span.end();
|
|
102
110
|
}
|
|
103
|
-
setConfig(config) {
|
|
104
|
-
const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
|
|
105
|
-
this.config = appConfig;
|
|
106
|
-
this.runtimeEnvironment = runtimeEnvironment;
|
|
107
|
-
this.globalData = globalData;
|
|
108
|
-
}
|
|
109
111
|
getConfig() {
|
|
110
112
|
return this.config;
|
|
111
113
|
}
|
|
@@ -163,26 +165,17 @@ export class LwrApp {
|
|
|
163
165
|
});
|
|
164
166
|
});
|
|
165
167
|
}
|
|
166
|
-
|
|
167
|
-
this.server?.close &&
|
|
168
|
+
close() {
|
|
169
|
+
this.server?.close && this.server.close();
|
|
168
170
|
}
|
|
169
171
|
// Get the underlying server (e.g. express, koa...)
|
|
170
172
|
getInternalServer() {
|
|
171
173
|
return this.app.getImpl();
|
|
172
174
|
}
|
|
173
|
-
// Return the public server interface which is compatible with all server types
|
|
174
|
-
getServer() {
|
|
175
|
-
return {
|
|
176
|
-
use: this.app.use.bind(this.app),
|
|
177
|
-
all: this.app.all.bind(this.app),
|
|
178
|
-
get: this.app.get.bind(this.app),
|
|
179
|
-
post: this.app.post.bind(this.app),
|
|
180
|
-
getRegexWildcard: this.app.getRegexWildcard.bind(this.app),
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
175
|
}
|
|
184
176
|
export function createServer(config) {
|
|
185
|
-
|
|
177
|
+
const configs = loadConfig(config);
|
|
178
|
+
return new LwrApp(configs);
|
|
186
179
|
}
|
|
187
180
|
export async function generateStaticSite(config) {
|
|
188
181
|
config = config || {};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { LWC_VERSION, LWR_VERSION, PWA_KIT_RUNTIME_VERSION, NODE_VERSION } from '@lwrjs/config';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
const baseHtml = `<!DOCTYPE html>
|
|
4
|
+
<html lang="en">
|
|
5
|
+
<head>
|
|
6
|
+
<meta charset="utf-8" />
|
|
7
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
|
|
8
|
+
<title>Site Information</title>
|
|
9
|
+
<style>
|
|
10
|
+
body {
|
|
11
|
+
font-family: Arial, sans-serif;
|
|
12
|
+
margin: 0;
|
|
13
|
+
padding: 20px;
|
|
14
|
+
background-color: #f9f9f9;
|
|
15
|
+
color: #333;
|
|
16
|
+
display: flex;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.container {
|
|
20
|
+
max-width: 800px;
|
|
21
|
+
width: 100%;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
h1, h2 {
|
|
25
|
+
color: #555;
|
|
26
|
+
margin-bottom: 16px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
ul {
|
|
30
|
+
list-style-type: none;
|
|
31
|
+
padding: 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
li {
|
|
35
|
+
background-color: #fff;
|
|
36
|
+
border: 1px solid #ddd;
|
|
37
|
+
margin-bottom: 10px;
|
|
38
|
+
padding: 10px;
|
|
39
|
+
border-radius: 4px;
|
|
40
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
41
|
+
display: flex;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.key {
|
|
45
|
+
margin-right: 10px;
|
|
46
|
+
color: #777;
|
|
47
|
+
font-weight: normal;
|
|
48
|
+
min-width: 200px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.val {
|
|
52
|
+
font-weight: bold;
|
|
53
|
+
color: steelblue;
|
|
54
|
+
font-size: 1.1em;
|
|
55
|
+
flex-grow: 1;
|
|
56
|
+
text-align: left;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.data-container {
|
|
60
|
+
padding: 20px;
|
|
61
|
+
border: 1px solid #333;
|
|
62
|
+
border-radius: 5px;
|
|
63
|
+
white-space: pre;
|
|
64
|
+
font-family: monospace;
|
|
65
|
+
text-align: justify;
|
|
66
|
+
};
|
|
67
|
+
</style>
|
|
68
|
+
</head>
|
|
69
|
+
<body>
|
|
70
|
+
<div class="container">
|
|
71
|
+
<h1>Site Information</h1>
|
|
72
|
+
<h2>Environment</h2>
|
|
73
|
+
{{ versionInfo }}
|
|
74
|
+
<h2>Metadata</h2>
|
|
75
|
+
{{ metadata }}
|
|
76
|
+
</div>
|
|
77
|
+
</body>
|
|
78
|
+
</html>
|
|
79
|
+
`;
|
|
80
|
+
export default async function siteInfoHandler(_request, context) {
|
|
81
|
+
const versionInfo = {
|
|
82
|
+
'LWR Version': LWR_VERSION,
|
|
83
|
+
'LWC Version': LWC_VERSION,
|
|
84
|
+
'Node Version': NODE_VERSION,
|
|
85
|
+
'PWA Kit Runtime Version': PWA_KIT_RUNTIME_VERSION,
|
|
86
|
+
};
|
|
87
|
+
let versionInfoString = '<ul>';
|
|
88
|
+
for (const key in versionInfo) {
|
|
89
|
+
if (versionInfo[key] !== 'note-provided') {
|
|
90
|
+
versionInfoString += `<li><span class="key">${key}:</span><span class="val">${versionInfo[key]}</span></li>\n`;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
versionInfoString += '</ul>';
|
|
94
|
+
// Get any provided metadata from site/.metadata/runtime-info.json
|
|
95
|
+
const providedMetadataPath = `${context.rootDir}/site/.metadata/runtime-info.json`;
|
|
96
|
+
let providedMetadata = {};
|
|
97
|
+
if (fs.existsSync(providedMetadataPath)) {
|
|
98
|
+
providedMetadata = JSON.parse(fs.readFileSync(providedMetadataPath, 'utf-8'));
|
|
99
|
+
}
|
|
100
|
+
let providedInfoString = '<ul>';
|
|
101
|
+
for (const key in providedMetadata) {
|
|
102
|
+
if (providedMetadata[key] !== 'note-provided') {
|
|
103
|
+
const value = typeof providedMetadata[key] === 'object'
|
|
104
|
+
? `<div class="data-container val">${JSON.stringify(providedMetadata[key], null, 2)}</div>`
|
|
105
|
+
: `<span class="val">${providedMetadata[key]}</span>`;
|
|
106
|
+
providedInfoString += `<li><span class="key">${key}:</span>${value}</li>\n`;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
providedInfoString += '</ul>';
|
|
110
|
+
let infoHtml = baseHtml;
|
|
111
|
+
infoHtml = infoHtml.replace('{{ versionInfo }}', versionInfoString);
|
|
112
|
+
infoHtml = infoHtml.replace('{{ metadata }}', providedInfoString);
|
|
113
|
+
return {
|
|
114
|
+
body: infoHtml,
|
|
115
|
+
headers: {
|
|
116
|
+
'content-type': `text/html; charset=utf-8`,
|
|
117
|
+
},
|
|
118
|
+
cache: {
|
|
119
|
+
ttl: '200s',
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=route-handler.js.map
|
|
@@ -3,6 +3,30 @@ import { DiagnosticsError } from '@lwrjs/diagnostics';
|
|
|
3
3
|
import { RequestHandlerSpan, getTracer } from '@lwrjs/instrumentation';
|
|
4
4
|
import { getAssetIdentity } from './utils/identity.js';
|
|
5
5
|
import { handleErrors } from './utils/error-handling.js';
|
|
6
|
+
import fs from 'fs-extra';
|
|
7
|
+
export function assetMiddleware(app, context) {
|
|
8
|
+
const paths = context.appConfig.assets.map((config) => {
|
|
9
|
+
const assetDirConfig = config;
|
|
10
|
+
let urlPath = config.urlPath;
|
|
11
|
+
// If this is a root config add a /:filename path to match any file in the root. The middleware will fall through if there is no match.
|
|
12
|
+
if (assetDirConfig.root) {
|
|
13
|
+
urlPath = '/:filename';
|
|
14
|
+
}
|
|
15
|
+
else if (assetDirConfig.dir) {
|
|
16
|
+
urlPath += app.getRegexWildcard();
|
|
17
|
+
}
|
|
18
|
+
return urlPath;
|
|
19
|
+
});
|
|
20
|
+
app.get([
|
|
21
|
+
// De-dupe paths (i.e. root path may have been added more than once)
|
|
22
|
+
...[...new Set(paths)],
|
|
23
|
+
'/:apiVersion/:assetType(asset|content-asset)/:immutable?/s/:signature/' + app.getRegexWildcard(),
|
|
24
|
+
'/:apiVersion/:assetType(asset|content-asset)/:immutable?/' + app.getRegexWildcard(),
|
|
25
|
+
], handleErrors(createAssetMiddleware(context)));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create middleware function to handle get assets requests
|
|
29
|
+
*/
|
|
6
30
|
function createAssetMiddleware(context) {
|
|
7
31
|
const { assetRegistry, runtimeEnvironment: { basePath }, } = context;
|
|
8
32
|
return async (req, res, next) => {
|
|
@@ -12,24 +36,22 @@ function createAssetMiddleware(context) {
|
|
|
12
36
|
assetId.specifier = path.join(basePath, assetId.specifier);
|
|
13
37
|
}
|
|
14
38
|
try {
|
|
15
|
-
|
|
39
|
+
let asset;
|
|
16
40
|
const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
|
|
41
|
+
// Check if this asset is available externally
|
|
17
42
|
if (assetUri.external) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
43
|
+
// This asset is marked external but hit the middleware anyway
|
|
44
|
+
// Check if we have this file locally, if not, send a 302 to
|
|
45
|
+
// redirect to the external URL
|
|
46
|
+
asset = await getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment);
|
|
47
|
+
// Verify the content actually exists locally
|
|
48
|
+
if (!fs.existsSync(asset.entry) && assetUri.uri.startsWith('/mobify/bundle')) {
|
|
49
|
+
return sendRedirect(res, assetUri);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
asset = await getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment);
|
|
24
54
|
}
|
|
25
|
-
const asset = await getTracer().trace({
|
|
26
|
-
name: RequestHandlerSpan.GetAsset,
|
|
27
|
-
attributes: {
|
|
28
|
-
specifier: assetId.specifier,
|
|
29
|
-
},
|
|
30
|
-
}, () => {
|
|
31
|
-
return assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
|
|
32
|
-
});
|
|
33
55
|
if (req.isSiteGeneration()) {
|
|
34
56
|
res.setSiteGenerationMetadata({ asset });
|
|
35
57
|
}
|
|
@@ -58,24 +80,29 @@ function createAssetMiddleware(context) {
|
|
|
58
80
|
}
|
|
59
81
|
};
|
|
60
82
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
return
|
|
83
|
+
/**
|
|
84
|
+
* Get the asset definition if asset is local
|
|
85
|
+
*/
|
|
86
|
+
async function getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment) {
|
|
87
|
+
const asset = await getTracer().trace({
|
|
88
|
+
name: RequestHandlerSpan.GetAsset,
|
|
89
|
+
attributes: {
|
|
90
|
+
specifier: assetId.specifier,
|
|
91
|
+
url: req.originalUrl,
|
|
92
|
+
},
|
|
93
|
+
}, () => {
|
|
94
|
+
return assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
|
|
73
95
|
});
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
96
|
+
return asset;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Send a redirect (302) response
|
|
100
|
+
*/
|
|
101
|
+
function sendRedirect(res, assetUri) {
|
|
102
|
+
res.set({
|
|
103
|
+
Location: assetUri.uri,
|
|
104
|
+
'cache-control': 'public, max-age=60',
|
|
105
|
+
});
|
|
106
|
+
res.sendStatus(302);
|
|
80
107
|
}
|
|
81
108
|
//# sourceMappingURL=asset-middleware.js.map
|
|
@@ -20,6 +20,12 @@ function createBundleMiddleware(context) {
|
|
|
20
20
|
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
+
if (!req.validateApiVersion(appConfig)) {
|
|
24
|
+
res.status(400);
|
|
25
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_API_VERSION(req.params.apiVersion, appConfig.apiVersion)
|
|
26
|
+
.message);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
23
29
|
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
24
30
|
const importer = req.query.importer
|
|
25
31
|
? await getRequestImporter(req, moduleRegistry, runtimeParams)
|
|
@@ -34,6 +40,7 @@ function createBundleMiddleware(context) {
|
|
|
34
40
|
name: RequestHandlerSpan.GetBundle,
|
|
35
41
|
attributes: {
|
|
36
42
|
specifier: moduleId.specifier,
|
|
43
|
+
url: req.originalUrl,
|
|
37
44
|
},
|
|
38
45
|
}, () => {
|
|
39
46
|
return moduleBundler.getModuleBundle(moduleId,
|
|
@@ -15,6 +15,9 @@ function createMappingMiddleware(context) {
|
|
|
15
15
|
const { moduleIds } = getMappingIdentity(req);
|
|
16
16
|
const importMetadata = await getTracer().trace({
|
|
17
17
|
name: RequestHandlerSpan.GetMapping,
|
|
18
|
+
attributes: {
|
|
19
|
+
url: req.originalUrl,
|
|
20
|
+
},
|
|
18
21
|
}, () => {
|
|
19
22
|
return getImportMetadataMappings(moduleIds, runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler);
|
|
20
23
|
});
|
|
@@ -19,6 +19,12 @@ function createModuleMiddleware(context) {
|
|
|
19
19
|
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
20
20
|
return;
|
|
21
21
|
}
|
|
22
|
+
if (!req.validateApiVersion(appConfig)) {
|
|
23
|
+
res.status(400);
|
|
24
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_API_VERSION(req.params.apiVersion, appConfig.apiVersion)
|
|
25
|
+
.message);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
22
28
|
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(defaultRuntimeEnvironment);
|
|
23
29
|
const importer = req.query.importer
|
|
24
30
|
? await getRequestImporter(req, moduleRegistry, runtimeParams)
|
|
@@ -32,6 +38,7 @@ function createModuleMiddleware(context) {
|
|
|
32
38
|
name: RequestHandlerSpan.GetModule,
|
|
33
39
|
attributes: {
|
|
34
40
|
specifier: moduleId.specifier,
|
|
41
|
+
url: req.originalUrl,
|
|
35
42
|
},
|
|
36
43
|
}, () => {
|
|
37
44
|
return moduleRegistry.getLinkedModule(moduleId,
|
|
@@ -7,15 +7,21 @@
|
|
|
7
7
|
*
|
|
8
8
|
*/
|
|
9
9
|
import { logger } from '@lwrjs/diagnostics';
|
|
10
|
+
import { parseRequestDepthHeader } from '@lwrjs/shared-utils';
|
|
10
11
|
const MRT_REQUEST_CLASS = 'X-Mobify-Request-Class';
|
|
11
12
|
const MRT_REQUEST_CLASS_KEY = MRT_REQUEST_CLASS.toLowerCase();
|
|
12
13
|
export function requestProcessorMiddleware(app, context) {
|
|
13
14
|
const { basePath } = context.runtimeEnvironment;
|
|
14
|
-
app.use(async (req,
|
|
15
|
+
app.use(async (req, res, next) => {
|
|
15
16
|
let requestClass;
|
|
17
|
+
let requestDepth;
|
|
16
18
|
if (req.headers) {
|
|
17
19
|
// If debug print log all the headers
|
|
18
20
|
if (logger.isDebugEnabled()) {
|
|
21
|
+
logger.debug({
|
|
22
|
+
label: `request-processor-middleware`,
|
|
23
|
+
message: `Request: ${req.originalUrl}`,
|
|
24
|
+
});
|
|
19
25
|
// Loop through and print each header
|
|
20
26
|
for (const headerName in req.headers) {
|
|
21
27
|
logger.debug({
|
|
@@ -25,6 +31,16 @@ export function requestProcessorMiddleware(app, context) {
|
|
|
25
31
|
}
|
|
26
32
|
}
|
|
27
33
|
requestClass = req.headers[MRT_REQUEST_CLASS_KEY];
|
|
34
|
+
requestDepth = parseRequestDepthHeader(req.headers);
|
|
35
|
+
}
|
|
36
|
+
// TODO Clean up once we have a long term solution
|
|
37
|
+
if (requestDepth && requestDepth > 1) {
|
|
38
|
+
logger.warn({
|
|
39
|
+
label: 'request-processor-middleware',
|
|
40
|
+
message: 'Lambda SSR request cycle detected',
|
|
41
|
+
});
|
|
42
|
+
// Return 400 Too Many Requests status
|
|
43
|
+
return res.status(400).send('Request depth limit reached');
|
|
28
44
|
}
|
|
29
45
|
if (req.headers && typeof requestClass === 'string') {
|
|
30
46
|
const parsedRequestClass = parseRequestClass(requestClass);
|
|
@@ -8,7 +8,7 @@ function createReturnStatus(error, url) {
|
|
|
8
8
|
if (error instanceof LwrUnresolvableError) {
|
|
9
9
|
return { status: 404, message: error.message };
|
|
10
10
|
}
|
|
11
|
-
return { status: 500, message: descriptions.
|
|
11
|
+
return { status: 500, message: descriptions.SERVER.SERVER_ERROR(url).message };
|
|
12
12
|
}
|
|
13
13
|
export function handleErrors(middleware) {
|
|
14
14
|
return async (req, res, next) => {
|
|
@@ -44,7 +44,11 @@ export function getResourceIdentity(req) {
|
|
|
44
44
|
}
|
|
45
45
|
export function getAssetIdentity(req) {
|
|
46
46
|
const { signature, immutable, assetType: type } = req.params;
|
|
47
|
-
const specifier = type
|
|
47
|
+
const specifier = type
|
|
48
|
+
? process.platform === 'win32'
|
|
49
|
+
? req.params[0]
|
|
50
|
+
: '/' + req.params[0]
|
|
51
|
+
: req.originalUrl.split('?')[0];
|
|
48
52
|
if (validateSpecifier(specifier) === false) {
|
|
49
53
|
throw createSingleDiagnosticError({
|
|
50
54
|
description: descriptions.UNRESOLVABLE.INVALID_SPECIFIER(specifier),
|
|
@@ -40,13 +40,16 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
40
40
|
const resolve = req.isJsonRequest() ? viewHandler.getViewJson : viewHandler.getViewContent;
|
|
41
41
|
let viewResponse;
|
|
42
42
|
let resolvedRoute;
|
|
43
|
+
let traceId;
|
|
43
44
|
try {
|
|
44
45
|
viewResponse = await getTracer().trace({
|
|
45
46
|
name: RequestHandlerSpan.GetView,
|
|
46
47
|
attributes: {
|
|
47
48
|
view: route.id,
|
|
49
|
+
url: req.originalUrl,
|
|
48
50
|
},
|
|
49
|
-
}, () => {
|
|
51
|
+
}, (span) => {
|
|
52
|
+
traceId = span.traceId;
|
|
50
53
|
return resolve.call(viewHandler, viewRequest, route, runtimeEnvironment, runtimeParams);
|
|
51
54
|
});
|
|
52
55
|
resolvedRoute = route;
|
|
@@ -84,6 +87,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
84
87
|
res.setHeader('cache-control', `public, max-age=${cacheTtl}`);
|
|
85
88
|
}
|
|
86
89
|
}
|
|
90
|
+
if (traceId?.length) {
|
|
91
|
+
res.setHeader('x-trace-id', traceId);
|
|
92
|
+
}
|
|
87
93
|
const status = resolvedRoute.status || viewResponse.status || 200;
|
|
88
94
|
res.status(status);
|
|
89
95
|
res.send(viewResponse.body);
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.12.0-alpha.
|
|
7
|
+
"version": "0.12.0-alpha.20",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -27,7 +27,11 @@
|
|
|
27
27
|
"import": "./build/es/middleware.js",
|
|
28
28
|
"require": "./build/cjs/middleware.cjs"
|
|
29
29
|
},
|
|
30
|
-
"./package": "./package.cjs"
|
|
30
|
+
"./package": "./package.cjs",
|
|
31
|
+
"./info/route-handler": {
|
|
32
|
+
"import": "./build/es/info/route-handler.js",
|
|
33
|
+
"require": "./build/cjs/info/route-handler.cjs"
|
|
34
|
+
}
|
|
31
35
|
},
|
|
32
36
|
"files": [
|
|
33
37
|
"build/**/*.js",
|
|
@@ -39,44 +43,46 @@
|
|
|
39
43
|
"build": "tsc -b"
|
|
40
44
|
},
|
|
41
45
|
"dependencies": {
|
|
42
|
-
"@lwrjs/app-service": "0.12.0-alpha.
|
|
43
|
-
"@lwrjs/asset-registry": "0.12.0-alpha.
|
|
44
|
-
"@lwrjs/asset-transformer": "0.12.0-alpha.
|
|
45
|
-
"@lwrjs/base-view-provider": "0.12.0-alpha.
|
|
46
|
-
"@lwrjs/base-view-transformer": "0.12.0-alpha.
|
|
47
|
-
"@lwrjs/client-modules": "0.12.0-alpha.
|
|
48
|
-
"@lwrjs/config": "0.12.0-alpha.
|
|
49
|
-
"@lwrjs/diagnostics": "0.12.0-alpha.
|
|
50
|
-
"@lwrjs/esbuild": "0.12.0-alpha.
|
|
51
|
-
"@lwrjs/fs-asset-provider": "0.12.0-alpha.
|
|
52
|
-
"@lwrjs/fs-watch": "0.12.0-alpha.
|
|
53
|
-
"@lwrjs/html-view-provider": "0.12.0-alpha.
|
|
54
|
-
"@lwrjs/instrumentation": "0.12.0-alpha.
|
|
55
|
-
"@lwrjs/loader": "0.12.0-alpha.
|
|
56
|
-
"@lwrjs/lwc-module-provider": "0.12.0-alpha.
|
|
57
|
-
"@lwrjs/
|
|
58
|
-
"@lwrjs/
|
|
59
|
-
"@lwrjs/module-
|
|
60
|
-
"@lwrjs/
|
|
61
|
-
"@lwrjs/
|
|
62
|
-
"@lwrjs/
|
|
63
|
-
"@lwrjs/
|
|
64
|
-
"@lwrjs/
|
|
65
|
-
"@lwrjs/
|
|
66
|
-
"@lwrjs/
|
|
67
|
-
"@lwrjs/
|
|
68
|
-
"@lwrjs/
|
|
69
|
-
"
|
|
46
|
+
"@lwrjs/app-service": "0.12.0-alpha.20",
|
|
47
|
+
"@lwrjs/asset-registry": "0.12.0-alpha.20",
|
|
48
|
+
"@lwrjs/asset-transformer": "0.12.0-alpha.20",
|
|
49
|
+
"@lwrjs/base-view-provider": "0.12.0-alpha.20",
|
|
50
|
+
"@lwrjs/base-view-transformer": "0.12.0-alpha.20",
|
|
51
|
+
"@lwrjs/client-modules": "0.12.0-alpha.20",
|
|
52
|
+
"@lwrjs/config": "0.12.0-alpha.20",
|
|
53
|
+
"@lwrjs/diagnostics": "0.12.0-alpha.20",
|
|
54
|
+
"@lwrjs/esbuild": "0.12.0-alpha.20",
|
|
55
|
+
"@lwrjs/fs-asset-provider": "0.12.0-alpha.20",
|
|
56
|
+
"@lwrjs/fs-watch": "0.12.0-alpha.20",
|
|
57
|
+
"@lwrjs/html-view-provider": "0.12.0-alpha.20",
|
|
58
|
+
"@lwrjs/instrumentation": "0.12.0-alpha.20",
|
|
59
|
+
"@lwrjs/loader": "0.12.0-alpha.20",
|
|
60
|
+
"@lwrjs/lwc-module-provider": "0.12.0-alpha.20",
|
|
61
|
+
"@lwrjs/lwc-ssr": "0.12.0-alpha.20",
|
|
62
|
+
"@lwrjs/markdown-view-provider": "0.12.0-alpha.20",
|
|
63
|
+
"@lwrjs/module-bundler": "0.12.0-alpha.20",
|
|
64
|
+
"@lwrjs/module-registry": "0.12.0-alpha.20",
|
|
65
|
+
"@lwrjs/npm-module-provider": "0.12.0-alpha.20",
|
|
66
|
+
"@lwrjs/nunjucks-view-provider": "0.12.0-alpha.20",
|
|
67
|
+
"@lwrjs/o11y": "0.12.0-alpha.20",
|
|
68
|
+
"@lwrjs/resource-registry": "0.12.0-alpha.20",
|
|
69
|
+
"@lwrjs/router": "0.12.0-alpha.20",
|
|
70
|
+
"@lwrjs/server": "0.12.0-alpha.20",
|
|
71
|
+
"@lwrjs/shared-utils": "0.12.0-alpha.20",
|
|
72
|
+
"@lwrjs/static": "0.12.0-alpha.20",
|
|
73
|
+
"@lwrjs/view-registry": "0.12.0-alpha.20",
|
|
74
|
+
"chokidar": "^3.6.0",
|
|
70
75
|
"esbuild": "^0.9.7",
|
|
71
|
-
"fs-extra": "^11.
|
|
76
|
+
"fs-extra": "^11.2.0",
|
|
72
77
|
"path-to-regexp": "^6.2.0",
|
|
73
78
|
"qs": "^6.11.2",
|
|
74
79
|
"rollup": "^2.78.0",
|
|
75
|
-
"ws": "^8.
|
|
80
|
+
"ws": "^8.16.0"
|
|
76
81
|
},
|
|
77
82
|
"devDependencies": {
|
|
78
|
-
"@lwrjs/types": "0.12.0-alpha.
|
|
79
|
-
"@types/ws": "^8.5.
|
|
83
|
+
"@lwrjs/types": "0.12.0-alpha.20",
|
|
84
|
+
"@types/ws": "^8.5.10",
|
|
85
|
+
"mock-fs": "^5.2.0"
|
|
80
86
|
},
|
|
81
87
|
"peerDependencies": {
|
|
82
88
|
"lwc": ">= 2.x"
|
|
@@ -87,5 +93,5 @@
|
|
|
87
93
|
"volta": {
|
|
88
94
|
"extends": "../../../package.json"
|
|
89
95
|
},
|
|
90
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "ae1793e34eaf4e9b97996d7aea9031908b23a13a"
|
|
91
97
|
}
|