@lwrjs/core 0.12.0-alpha.9 → 0.13.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/context/provider.cjs +7 -2
- package/build/cjs/index.cjs +19 -25
- package/build/cjs/middleware/asset-middleware.cjs +41 -29
- package/build/cjs/middleware/request-processor-middleware.cjs +15 -1
- package/build/cjs/middleware/utils/error-handling.cjs +1 -1
- package/build/cjs/middleware/view-middleware.cjs +10 -2
- package/build/cjs/tools/static-generation.cjs +41 -6
- package/build/cjs/tools/utils/network-dispatcher.cjs +3 -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/middleware/asset-middleware.js +60 -34
- package/build/es/middleware/request-processor-middleware.js +17 -1
- package/build/es/middleware/utils/error-handling.js +1 -1
- package/build/es/middleware/view-middleware.js +9 -1
- package/build/es/tools/static-generation.d.ts +4 -0
- package/build/es/tools/static-generation.js +51 -11
- package/build/es/tools/utils/network-dispatcher.js +5 -2
- package/package.json +36 -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 || {};
|
|
@@ -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,24 +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,
|
|
59
|
-
url: req.originalUrl
|
|
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);
|
|
60
70
|
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
}
|
|
71
|
+
} else {
|
|
72
|
+
asset = await getAssetDefinition(assetId, req, assetRegistry, signature, runtimeEnvironment);
|
|
73
|
+
}
|
|
64
74
|
if (req.isSiteGeneration()) {
|
|
65
75
|
res.setSiteGenerationMetadata({asset});
|
|
66
76
|
}
|
|
@@ -82,20 +92,22 @@ function createAssetMiddleware(context) {
|
|
|
82
92
|
}
|
|
83
93
|
};
|
|
84
94
|
}
|
|
85
|
-
function
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
} else if (assetDirConfig.dir) {
|
|
92
|
-
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
|
|
93
101
|
}
|
|
94
|
-
|
|
102
|
+
}, () => {
|
|
103
|
+
return assetRegistry.getAsset({...assetId, signature}, runtimeEnvironment, req.isSiteGeneration());
|
|
95
104
|
});
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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);
|
|
101
113
|
}
|
|
@@ -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 > 0) {
|
|
55
|
+
import_diagnostics.logger.error({
|
|
56
|
+
label: "request-processor-middleware",
|
|
57
|
+
message: `Lambda SSR request cycle detected: ${req.originalUrl}`
|
|
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) => {
|
|
@@ -66,14 +66,19 @@ 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
74
|
view: route.id,
|
|
74
|
-
url: req.originalUrl
|
|
75
|
+
url: req.originalUrl,
|
|
76
|
+
host: runtimeParams.host,
|
|
77
|
+
basePath: runtimeParams.basePath,
|
|
78
|
+
locale: runtimeParams.locale
|
|
75
79
|
}
|
|
76
|
-
}, () => {
|
|
80
|
+
}, (span) => {
|
|
81
|
+
traceId = span.traceId;
|
|
77
82
|
return resolve.call(viewHandler, viewRequest, route, runtimeEnvironment, runtimeParams);
|
|
78
83
|
});
|
|
79
84
|
resolvedRoute = route;
|
|
@@ -106,6 +111,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
106
111
|
res.setHeader("cache-control", `public, max-age=${cacheTtl}`);
|
|
107
112
|
}
|
|
108
113
|
}
|
|
114
|
+
if (traceId?.length) {
|
|
115
|
+
res.setHeader("x-trace-id", traceId);
|
|
116
|
+
}
|
|
109
117
|
const status = resolvedRoute.status || viewResponse.status || 200;
|
|
110
118
|
res.status(status);
|
|
111
119
|
res.send(viewResponse.body);
|
|
@@ -36,6 +36,7 @@ var import_fs_extra = __toModule(require("fs-extra"));
|
|
|
36
36
|
var import_stream = __toModule(require("./utils/stream.cjs"));
|
|
37
37
|
var import_dir = __toModule(require("./utils/dir.cjs"));
|
|
38
38
|
var import_config = __toModule(require("@lwrjs/config"));
|
|
39
|
+
var import_url = __toModule(require("url"));
|
|
39
40
|
var SiteGenerator = class {
|
|
40
41
|
async buildStaticApplication(config, dispatcher) {
|
|
41
42
|
const startTime = import_perf_hooks.performance.now();
|
|
@@ -161,6 +162,14 @@ var SiteGenerator = class {
|
|
|
161
162
|
}
|
|
162
163
|
async handleJavascriptResource(url, context, siteConfig, dispatcher) {
|
|
163
164
|
const {outputDir} = siteConfig;
|
|
165
|
+
const moduleDefinition = context.fs?.metadata?.moduleDefinition;
|
|
166
|
+
const bundleConfig = moduleDefinition?.config || {};
|
|
167
|
+
const siteBundles = siteConfig?.siteMetadata?.getSiteBundles()?.bundles;
|
|
168
|
+
const specifier = moduleDefinition?.specifier;
|
|
169
|
+
if ((0, import_shared_utils.isExternalSpecifier)(specifier, bundleConfig)) {
|
|
170
|
+
this.handleExternalBundle(specifier, siteBundles, bundleConfig.external, outputDir);
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
164
173
|
const normalizedUrl = decodeURIComponent(url);
|
|
165
174
|
(0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
|
|
166
175
|
const ext = (0, import_path.extname)(normalizedUrl);
|
|
@@ -173,17 +182,26 @@ var SiteGenerator = class {
|
|
|
173
182
|
siteConfig.urlRewriteMap.set(normalizedUrl.substring(0, normalizedUrl.indexOf("/v/")), normalizedUrl);
|
|
174
183
|
siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf("%2Fv%2F")), normalizedUrl);
|
|
175
184
|
}
|
|
176
|
-
const moduleDefinition = context.fs?.metadata?.moduleDefinition;
|
|
177
185
|
if (moduleDefinition) {
|
|
178
186
|
const imports = moduleDefinition.linkedModuleRecord?.imports || moduleDefinition.bundleRecord?.imports || [];
|
|
179
187
|
for (const importModule of imports) {
|
|
180
|
-
const
|
|
181
|
-
|
|
188
|
+
const importSpecifier = importModule.specifier;
|
|
189
|
+
if ((0, import_shared_utils.isExternalSpecifier)(importSpecifier, bundleConfig)) {
|
|
190
|
+
this.handleExternalBundle(importSpecifier, siteBundles, bundleConfig.external, outputDir);
|
|
191
|
+
} else {
|
|
192
|
+
const jsUri = importSpecifier.startsWith("/") ? importSpecifier : (0, import_shared_utils.getSpecifier)(importModule);
|
|
193
|
+
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
194
|
+
}
|
|
182
195
|
}
|
|
183
196
|
const dynamicImports = moduleDefinition.linkedModuleRecord?.dynamicImports || moduleDefinition.bundleRecord?.dynamicImports || [];
|
|
184
197
|
for (const importModule of dynamicImports) {
|
|
185
|
-
const
|
|
186
|
-
|
|
198
|
+
const importSpecifier = importModule.specifier;
|
|
199
|
+
if ((0, import_shared_utils.isExternalSpecifier)(importSpecifier, bundleConfig)) {
|
|
200
|
+
this.handleExternalBundle(importSpecifier, siteBundles, bundleConfig.external, outputDir);
|
|
201
|
+
} else {
|
|
202
|
+
const jsUri = importSpecifier.startsWith("/") ? importSpecifier : (0, import_shared_utils.getSpecifier)(importModule);
|
|
203
|
+
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
204
|
+
}
|
|
187
205
|
}
|
|
188
206
|
if (moduleDefinition.bundleRecord) {
|
|
189
207
|
this.addBundleToSiteMetadata(moduleDefinition, url, siteConfig);
|
|
@@ -195,14 +213,31 @@ var SiteGenerator = class {
|
|
|
195
213
|
}
|
|
196
214
|
await Promise.all(dispatchRequests);
|
|
197
215
|
}
|
|
216
|
+
handleExternalBundle(specifier, siteBundles, externals, outputDir) {
|
|
217
|
+
if (siteBundles && externals[specifier]?.startsWith(import_shared_utils.PROTOCOL_FILE) && !siteBundles[specifier]) {
|
|
218
|
+
const path = (0, import_shared_utils.normalizeFromFileURL)(externals[specifier], process.cwd());
|
|
219
|
+
const normalizedPath = decodeURIComponent(path);
|
|
220
|
+
(0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedPath), outputDir);
|
|
221
|
+
const ext = (0, import_path.extname)(normalizedPath);
|
|
222
|
+
const fullPath = (0, import_path.join)(outputDir, `${normalizedPath}${ext ? "" : ".js"}`);
|
|
223
|
+
import_fs_extra.default.copyFileSync((0, import_url.fileURLToPath)(externals[specifier]), fullPath);
|
|
224
|
+
const bundleMetadata = {
|
|
225
|
+
specifier,
|
|
226
|
+
path: normalizedPath,
|
|
227
|
+
imports: []
|
|
228
|
+
};
|
|
229
|
+
siteBundles[specifier] = bundleMetadata;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
198
232
|
addBundleToSiteMetadata(bundleDefinition, url, siteConfig) {
|
|
199
233
|
if (siteConfig.siteMetadata) {
|
|
200
234
|
const locale = siteConfig.locale;
|
|
201
235
|
const specifier = siteConfig.i18n.defaultLocale === locale ? bundleDefinition.specifier : `${bundleDefinition.specifier}|l/${locale}`;
|
|
202
236
|
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => (0, import_shared_utils.getSpecifier)(moduleRef)) || [];
|
|
203
237
|
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => (0, import_shared_utils.getSpecifier)(moduleRef));
|
|
238
|
+
const version = bundleDefinition.version === import_shared_utils.VERSION_NOT_PROVIDED ? void 0 : bundleDefinition.version;
|
|
204
239
|
const bundleMetadata = {
|
|
205
|
-
version
|
|
240
|
+
version,
|
|
206
241
|
path: decodeURIComponent(url),
|
|
207
242
|
includedModules: bundleDefinition.bundleRecord.includedModules || [],
|
|
208
243
|
imports,
|
|
@@ -79,16 +79,17 @@ var NetworkDispatcher = class {
|
|
|
79
79
|
const jsonResponse = JSON.parse(body);
|
|
80
80
|
resolve(jsonResponse);
|
|
81
81
|
} catch (err) {
|
|
82
|
+
const message = process.env.MRT_HMR !== "true" ? `unexpected response body: [${method}][${lang}] ${url}: '${body}'` : `unexpected response body: [${method}][${lang}] ${url}`;
|
|
82
83
|
if (import_diagnostics.logger.isDebugEnabled()) {
|
|
83
84
|
import_diagnostics.logger.warn({
|
|
84
85
|
label: `NetworkDispatcher`,
|
|
85
|
-
message
|
|
86
|
+
message,
|
|
86
87
|
additionalInfo: err
|
|
87
88
|
});
|
|
88
89
|
} else {
|
|
89
90
|
import_diagnostics.logger.warn({
|
|
90
91
|
label: `NetworkDispatcher`,
|
|
91
|
-
message
|
|
92
|
+
message
|
|
92
93
|
});
|
|
93
94
|
}
|
|
94
95
|
resolve({});
|
|
@@ -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 || {};
|
|
@@ -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,25 +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
|
-
url: req.originalUrl,
|
|
30
|
-
},
|
|
31
|
-
}, () => {
|
|
32
|
-
return assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
|
|
33
|
-
});
|
|
34
55
|
if (req.isSiteGeneration()) {
|
|
35
56
|
res.setSiteGenerationMetadata({ asset });
|
|
36
57
|
}
|
|
@@ -59,24 +80,29 @@ function createAssetMiddleware(context) {
|
|
|
59
80
|
}
|
|
60
81
|
};
|
|
61
82
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
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());
|
|
74
95
|
});
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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);
|
|
81
107
|
}
|
|
82
108
|
//# sourceMappingURL=asset-middleware.js.map
|
|
@@ -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 > 0) {
|
|
38
|
+
logger.error({
|
|
39
|
+
label: 'request-processor-middleware',
|
|
40
|
+
message: `Lambda SSR request cycle detected: ${req.originalUrl}`,
|
|
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) => {
|
|
@@ -40,14 +40,19 @@ 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,
|
|
48
49
|
url: req.originalUrl,
|
|
50
|
+
host: runtimeParams.host,
|
|
51
|
+
basePath: runtimeParams.basePath,
|
|
52
|
+
locale: runtimeParams.locale,
|
|
49
53
|
},
|
|
50
|
-
}, () => {
|
|
54
|
+
}, (span) => {
|
|
55
|
+
traceId = span.traceId;
|
|
51
56
|
return resolve.call(viewHandler, viewRequest, route, runtimeEnvironment, runtimeParams);
|
|
52
57
|
});
|
|
53
58
|
resolvedRoute = route;
|
|
@@ -85,6 +90,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
85
90
|
res.setHeader('cache-control', `public, max-age=${cacheTtl}`);
|
|
86
91
|
}
|
|
87
92
|
}
|
|
93
|
+
if (traceId?.length) {
|
|
94
|
+
res.setHeader('x-trace-id', traceId);
|
|
95
|
+
}
|
|
88
96
|
const status = resolvedRoute.status || viewResponse.status || 200;
|
|
89
97
|
res.status(status);
|
|
90
98
|
res.send(viewResponse.body);
|
|
@@ -40,6 +40,10 @@ export default class SiteGenerator {
|
|
|
40
40
|
* @param dispatcher - Network dispatcher
|
|
41
41
|
*/
|
|
42
42
|
private handleJavascriptResource;
|
|
43
|
+
/**
|
|
44
|
+
* If this is a file based external copy it to the site folder and add it to the bundle metadata
|
|
45
|
+
*/
|
|
46
|
+
private handleExternalBundle;
|
|
43
47
|
private addBundleToSiteMetadata;
|
|
44
48
|
private addResourceToSiteMetadata;
|
|
45
49
|
private addAssetToSiteMetadata;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { performance } from 'perf_hooks';
|
|
2
2
|
import { logger } from '@lwrjs/diagnostics';
|
|
3
|
-
import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, isExternalUrl, mimeLookup, getViewUri, sortLocalesByFallback, } from '@lwrjs/shared-utils';
|
|
3
|
+
import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, isExternalUrl, mimeLookup, getViewUri, sortLocalesByFallback, VERSION_NOT_PROVIDED, PROTOCOL_FILE, normalizeFromFileURL, isExternalSpecifier, } from '@lwrjs/shared-utils';
|
|
4
4
|
import { SiteMetadataImpl } from '@lwrjs/static/site-metadata';
|
|
5
5
|
import { join, dirname, extname, normalize } from 'path';
|
|
6
6
|
import fs from 'fs-extra';
|
|
7
7
|
import { writeResponse } from './utils/stream.js';
|
|
8
8
|
import { createResourceDir } from './utils/dir.js';
|
|
9
9
|
import { getRuntimeEnvironment } from '@lwrjs/config';
|
|
10
|
+
import { fileURLToPath } from 'url';
|
|
10
11
|
export default class SiteGenerator {
|
|
11
12
|
/**
|
|
12
13
|
* Build a static site in the configured directory
|
|
@@ -198,6 +199,14 @@ export default class SiteGenerator {
|
|
|
198
199
|
*/
|
|
199
200
|
async handleJavascriptResource(url, context, siteConfig, dispatcher) {
|
|
200
201
|
const { outputDir } = siteConfig;
|
|
202
|
+
const moduleDefinition = context.fs?.metadata?.moduleDefinition; // LinkedModuleDefinition | BundleDefinition
|
|
203
|
+
const bundleConfig = moduleDefinition?.config || {};
|
|
204
|
+
const siteBundles = siteConfig?.siteMetadata?.getSiteBundles()?.bundles;
|
|
205
|
+
const specifier = moduleDefinition?.specifier;
|
|
206
|
+
if (isExternalSpecifier(specifier, bundleConfig)) {
|
|
207
|
+
this.handleExternalBundle(specifier, siteBundles, bundleConfig.external, outputDir);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
201
210
|
const normalizedUrl = decodeURIComponent(url);
|
|
202
211
|
createResourceDir(dirname(normalizedUrl), outputDir);
|
|
203
212
|
const ext = extname(normalizedUrl);
|
|
@@ -223,26 +232,37 @@ export default class SiteGenerator {
|
|
|
223
232
|
siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf('%2Fv%2F')), normalizedUrl);
|
|
224
233
|
}
|
|
225
234
|
// Recursively traverse dependencies
|
|
226
|
-
const moduleDefinition = context.fs?.metadata?.moduleDefinition; // LinkedModuleDefinition | BundleDefinition
|
|
227
235
|
if (moduleDefinition) {
|
|
228
236
|
// Imports
|
|
229
237
|
const imports = moduleDefinition.linkedModuleRecord?.imports || moduleDefinition.bundleRecord?.imports || [];
|
|
230
238
|
// /1/module/esm/0/l/en-US/mi/lwc
|
|
231
239
|
for (const importModule of imports) {
|
|
232
|
-
const
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
240
|
+
const importSpecifier = importModule.specifier;
|
|
241
|
+
if (isExternalSpecifier(importSpecifier, bundleConfig)) {
|
|
242
|
+
this.handleExternalBundle(importSpecifier, siteBundles, bundleConfig.external, outputDir);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
const jsUri = importSpecifier.startsWith('/')
|
|
246
|
+
? importSpecifier
|
|
247
|
+
: getSpecifier(importModule);
|
|
248
|
+
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
249
|
+
}
|
|
236
250
|
}
|
|
237
251
|
// Dynamic imports
|
|
238
252
|
const dynamicImports = moduleDefinition.linkedModuleRecord?.dynamicImports ||
|
|
239
253
|
moduleDefinition.bundleRecord?.dynamicImports ||
|
|
240
254
|
[];
|
|
241
255
|
for (const importModule of dynamicImports) {
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
256
|
+
const importSpecifier = importModule.specifier;
|
|
257
|
+
if (isExternalSpecifier(importSpecifier, bundleConfig)) {
|
|
258
|
+
this.handleExternalBundle(importSpecifier, siteBundles, bundleConfig.external, outputDir);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
const jsUri = importSpecifier.startsWith('/')
|
|
262
|
+
? importSpecifier
|
|
263
|
+
: getSpecifier(importModule);
|
|
264
|
+
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
265
|
+
}
|
|
246
266
|
}
|
|
247
267
|
// If this is a bundle add it to the bundle metadata
|
|
248
268
|
if (moduleDefinition.bundleRecord) {
|
|
@@ -257,6 +277,25 @@ export default class SiteGenerator {
|
|
|
257
277
|
// -- Dispatch dependencies
|
|
258
278
|
await Promise.all(dispatchRequests);
|
|
259
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* If this is a file based external copy it to the site folder and add it to the bundle metadata
|
|
282
|
+
*/
|
|
283
|
+
handleExternalBundle(specifier, siteBundles, externals, outputDir) {
|
|
284
|
+
if (siteBundles && externals[specifier]?.startsWith(PROTOCOL_FILE) && !siteBundles[specifier]) {
|
|
285
|
+
const path = normalizeFromFileURL(externals[specifier], process.cwd());
|
|
286
|
+
const normalizedPath = decodeURIComponent(path);
|
|
287
|
+
createResourceDir(dirname(normalizedPath), outputDir);
|
|
288
|
+
const ext = extname(normalizedPath);
|
|
289
|
+
const fullPath = join(outputDir, `${normalizedPath}${ext ? '' : '.js'}`);
|
|
290
|
+
fs.copyFileSync(fileURLToPath(externals[specifier]), fullPath);
|
|
291
|
+
const bundleMetadata = {
|
|
292
|
+
specifier,
|
|
293
|
+
path: normalizedPath,
|
|
294
|
+
imports: [],
|
|
295
|
+
};
|
|
296
|
+
siteBundles[specifier] = bundleMetadata;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
260
299
|
addBundleToSiteMetadata(bundleDefinition, url, siteConfig) {
|
|
261
300
|
if (siteConfig.siteMetadata) {
|
|
262
301
|
const locale = siteConfig.locale;
|
|
@@ -265,8 +304,9 @@ export default class SiteGenerator {
|
|
|
265
304
|
: `${bundleDefinition.specifier}|l/${locale}`;
|
|
266
305
|
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => getSpecifier(moduleRef)) || [];
|
|
267
306
|
const dynamicImports = bundleDefinition.bundleRecord.dynamicImports?.map((moduleRef) => getSpecifier(moduleRef));
|
|
307
|
+
const version = bundleDefinition.version === VERSION_NOT_PROVIDED ? undefined : bundleDefinition.version;
|
|
268
308
|
const bundleMetadata = {
|
|
269
|
-
version
|
|
309
|
+
version,
|
|
270
310
|
path: decodeURIComponent(url),
|
|
271
311
|
includedModules: bundleDefinition.bundleRecord.includedModules || [],
|
|
272
312
|
imports,
|
|
@@ -53,17 +53,20 @@ export default class NetworkDispatcher {
|
|
|
53
53
|
resolve(jsonResponse);
|
|
54
54
|
}
|
|
55
55
|
catch (err) {
|
|
56
|
+
const message = process.env.MRT_HMR !== 'true' // avoid giant log messages during local dev
|
|
57
|
+
? `unexpected response body: [${method}][${lang}] ${url}: '${body}'`
|
|
58
|
+
: `unexpected response body: [${method}][${lang}] ${url}`;
|
|
56
59
|
if (logger.isDebugEnabled()) {
|
|
57
60
|
logger.warn({
|
|
58
61
|
label: `NetworkDispatcher`,
|
|
59
|
-
message
|
|
62
|
+
message,
|
|
60
63
|
additionalInfo: err,
|
|
61
64
|
});
|
|
62
65
|
}
|
|
63
66
|
else {
|
|
64
67
|
logger.warn({
|
|
65
68
|
label: `NetworkDispatcher`,
|
|
66
|
-
message
|
|
69
|
+
message,
|
|
67
70
|
});
|
|
68
71
|
}
|
|
69
72
|
resolve({});
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.13.0-alpha.0",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -43,45 +43,46 @@
|
|
|
43
43
|
"build": "tsc -b"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@lwrjs/app-service": "0.
|
|
47
|
-
"@lwrjs/asset-registry": "0.
|
|
48
|
-
"@lwrjs/asset-transformer": "0.
|
|
49
|
-
"@lwrjs/base-view-provider": "0.
|
|
50
|
-
"@lwrjs/base-view-transformer": "0.
|
|
51
|
-
"@lwrjs/client-modules": "0.
|
|
52
|
-
"@lwrjs/config": "0.
|
|
53
|
-
"@lwrjs/diagnostics": "0.
|
|
54
|
-
"@lwrjs/esbuild": "0.
|
|
55
|
-
"@lwrjs/fs-asset-provider": "0.
|
|
56
|
-
"@lwrjs/fs-watch": "0.
|
|
57
|
-
"@lwrjs/html-view-provider": "0.
|
|
58
|
-
"@lwrjs/instrumentation": "0.
|
|
59
|
-
"@lwrjs/loader": "0.
|
|
60
|
-
"@lwrjs/lwc-module-provider": "0.
|
|
61
|
-
"@lwrjs/lwc-ssr": "0.
|
|
62
|
-
"@lwrjs/markdown-view-provider": "0.
|
|
63
|
-
"@lwrjs/module-bundler": "0.
|
|
64
|
-
"@lwrjs/module-registry": "0.
|
|
65
|
-
"@lwrjs/npm-module-provider": "0.
|
|
66
|
-
"@lwrjs/nunjucks-view-provider": "0.
|
|
67
|
-
"@lwrjs/o11y": "0.
|
|
68
|
-
"@lwrjs/resource-registry": "0.
|
|
69
|
-
"@lwrjs/router": "0.
|
|
70
|
-
"@lwrjs/server": "0.
|
|
71
|
-
"@lwrjs/shared-utils": "0.
|
|
72
|
-
"@lwrjs/static": "0.
|
|
73
|
-
"@lwrjs/view-registry": "0.
|
|
74
|
-
"chokidar": "^3.
|
|
46
|
+
"@lwrjs/app-service": "0.13.0-alpha.0",
|
|
47
|
+
"@lwrjs/asset-registry": "0.13.0-alpha.0",
|
|
48
|
+
"@lwrjs/asset-transformer": "0.13.0-alpha.0",
|
|
49
|
+
"@lwrjs/base-view-provider": "0.13.0-alpha.0",
|
|
50
|
+
"@lwrjs/base-view-transformer": "0.13.0-alpha.0",
|
|
51
|
+
"@lwrjs/client-modules": "0.13.0-alpha.0",
|
|
52
|
+
"@lwrjs/config": "0.13.0-alpha.0",
|
|
53
|
+
"@lwrjs/diagnostics": "0.13.0-alpha.0",
|
|
54
|
+
"@lwrjs/esbuild": "0.13.0-alpha.0",
|
|
55
|
+
"@lwrjs/fs-asset-provider": "0.13.0-alpha.0",
|
|
56
|
+
"@lwrjs/fs-watch": "0.13.0-alpha.0",
|
|
57
|
+
"@lwrjs/html-view-provider": "0.13.0-alpha.0",
|
|
58
|
+
"@lwrjs/instrumentation": "0.13.0-alpha.0",
|
|
59
|
+
"@lwrjs/loader": "0.13.0-alpha.0",
|
|
60
|
+
"@lwrjs/lwc-module-provider": "0.13.0-alpha.0",
|
|
61
|
+
"@lwrjs/lwc-ssr": "0.13.0-alpha.0",
|
|
62
|
+
"@lwrjs/markdown-view-provider": "0.13.0-alpha.0",
|
|
63
|
+
"@lwrjs/module-bundler": "0.13.0-alpha.0",
|
|
64
|
+
"@lwrjs/module-registry": "0.13.0-alpha.0",
|
|
65
|
+
"@lwrjs/npm-module-provider": "0.13.0-alpha.0",
|
|
66
|
+
"@lwrjs/nunjucks-view-provider": "0.13.0-alpha.0",
|
|
67
|
+
"@lwrjs/o11y": "0.13.0-alpha.0",
|
|
68
|
+
"@lwrjs/resource-registry": "0.13.0-alpha.0",
|
|
69
|
+
"@lwrjs/router": "0.13.0-alpha.0",
|
|
70
|
+
"@lwrjs/server": "0.13.0-alpha.0",
|
|
71
|
+
"@lwrjs/shared-utils": "0.13.0-alpha.0",
|
|
72
|
+
"@lwrjs/static": "0.13.0-alpha.0",
|
|
73
|
+
"@lwrjs/view-registry": "0.13.0-alpha.0",
|
|
74
|
+
"chokidar": "^3.6.0",
|
|
75
75
|
"esbuild": "^0.9.7",
|
|
76
|
-
"fs-extra": "^11.
|
|
76
|
+
"fs-extra": "^11.2.0",
|
|
77
77
|
"path-to-regexp": "^6.2.0",
|
|
78
78
|
"qs": "^6.11.2",
|
|
79
79
|
"rollup": "^2.78.0",
|
|
80
|
-
"ws": "^8.
|
|
80
|
+
"ws": "^8.16.0"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@lwrjs/types": "0.
|
|
84
|
-
"@types/ws": "^8.5.
|
|
83
|
+
"@lwrjs/types": "0.13.0-alpha.0",
|
|
84
|
+
"@types/ws": "^8.5.10",
|
|
85
|
+
"mock-fs": "^5.2.0"
|
|
85
86
|
},
|
|
86
87
|
"peerDependencies": {
|
|
87
88
|
"lwc": ">= 2.x"
|
|
@@ -92,5 +93,5 @@
|
|
|
92
93
|
"volta": {
|
|
93
94
|
"extends": "../../../package.json"
|
|
94
95
|
},
|
|
95
|
-
"gitHead": "
|
|
96
|
+
"gitHead": "c5fe8db55c74513dbb0937d1b4568109715a13fb"
|
|
96
97
|
}
|