@lwrjs/core 0.10.0-alpha.9 → 0.11.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/index.cjs +15 -4
- package/build/cjs/middleware/asset-middleware.cjs +46 -24
- package/build/cjs/middleware/utils/identity.cjs +1 -1
- package/build/cjs/middleware/view-middleware.cjs +4 -0
- package/build/cjs/tools/static-generation.cjs +25 -7
- package/build/es/context/provider.d.ts +1 -1
- package/build/es/index.js +21 -5
- package/build/es/middleware/asset-middleware.js +56 -25
- package/build/es/middleware/hmr-middleware.d.ts +1 -1
- package/build/es/middleware/utils/error-handling.d.ts +1 -1
- package/build/es/middleware/utils/identity.js +1 -1
- package/build/es/middleware/utils/request.d.ts +1 -1
- package/build/es/middleware/view-middleware.js +6 -1
- package/build/es/tools/server-warmup.d.ts +1 -1
- package/build/es/tools/static-generation.d.ts +1 -1
- package/build/es/tools/static-generation.js +28 -6
- package/build/es/tools/utils/network-dispatcher.d.ts +1 -1
- package/build/es/tools/utils/stream.d.ts +2 -2
- package/package.json +38 -31
package/build/cjs/index.cjs
CHANGED
|
@@ -45,6 +45,7 @@ var import_asset_middleware = __toModule(require("./middleware/asset-middleware.
|
|
|
45
45
|
var import_view_middleware = __toModule(require("./middleware/view-middleware.cjs"));
|
|
46
46
|
var import_resource_middleware = __toModule(require("./middleware/resource-middleware.cjs"));
|
|
47
47
|
var import_hmr_middleware = __toModule(require("./middleware/hmr-middleware.cjs"));
|
|
48
|
+
var import_instrumentation = __toModule(require("@lwrjs/instrumentation"));
|
|
48
49
|
function initMiddleware(app, server, serverContext) {
|
|
49
50
|
app.useCompression();
|
|
50
51
|
(0, import_locale_middleware.localeMiddleware)(app, serverContext);
|
|
@@ -67,10 +68,11 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
67
68
|
if (hooks.length) {
|
|
68
69
|
const skipValidation = true;
|
|
69
70
|
await (0, import_config.executeConfigHooks)(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
|
|
71
|
+
(0, import_config.executeInstrumentationHooks)(hooks);
|
|
70
72
|
(0, import_config.executeStartHooks)(hooks, appConfig);
|
|
71
73
|
}
|
|
72
74
|
const services = await (0, import_modules.loadServices)(appConfig);
|
|
73
|
-
const serverContext = (0, import_server2.createServerContext)(appConfig, runtimeEnvironment, globalData);
|
|
75
|
+
const serverContext = (0, import_instrumentation.getTracer)().trace({name: import_instrumentation.CoreSpan.CreateServerContext}, () => (0, import_server2.createServerContext)(appConfig, runtimeEnvironment, globalData));
|
|
74
76
|
const providerContext = (0, import_provider.createProviderContext)(serverContext);
|
|
75
77
|
const {moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler} = serverContext;
|
|
76
78
|
const moduleProviders = createServices(services.moduleProviders, providerContext);
|
|
@@ -80,13 +82,16 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
80
82
|
const viewProviders = createServices(services.viewProviders, providerContext);
|
|
81
83
|
const viewTransformers = createServices(services.viewTransformers, providerContext);
|
|
82
84
|
const bundleProviders = createServices(services.bundleProviders, providerContext);
|
|
83
|
-
|
|
85
|
+
const uriTransformers = createServices(services.uriTransformers, providerContext);
|
|
84
86
|
assetRegistry.addAssetProviders(assetProviders);
|
|
85
|
-
assetRegistry.addAssetTransformers(assetTransformers);
|
|
87
|
+
assetRegistry.addAssetTransformers([...assetTransformers, ...uriTransformers]);
|
|
88
|
+
moduleBundler.addBundleProviders(bundleProviders);
|
|
89
|
+
moduleBundler.addBundleTransformers(uriTransformers);
|
|
90
|
+
moduleRegistry.addModuleProviders(moduleProviders);
|
|
86
91
|
resourceRegistry.addResourceProviders(resourceProviders);
|
|
92
|
+
resourceRegistry.addResourceTransformers(uriTransformers);
|
|
87
93
|
viewRegistry.addViewProviders(viewProviders);
|
|
88
94
|
viewRegistry.addViewTransformers(viewTransformers);
|
|
89
|
-
moduleBundler.addBundleProviders(bundleProviders);
|
|
90
95
|
await serverContext.viewRegistry.initializeViewProviders();
|
|
91
96
|
const routeHandlers = await (0, import_modules.loadRouteHandlers)(appConfig);
|
|
92
97
|
serverContext.routeHandlers = routeHandlers;
|
|
@@ -95,6 +100,7 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
95
100
|
var LwrApp = class {
|
|
96
101
|
constructor(config = {}) {
|
|
97
102
|
this.initialized = false;
|
|
103
|
+
const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.CreateServer});
|
|
98
104
|
const {appConfig, runtimeEnvironment, globalData} = (0, import_config.loadConfig)(config);
|
|
99
105
|
this.config = appConfig;
|
|
100
106
|
this.runtimeEnvironment = runtimeEnvironment;
|
|
@@ -102,6 +108,7 @@ var LwrApp = class {
|
|
|
102
108
|
const {basePath} = this.config;
|
|
103
109
|
this.app = (0, import_server.createInternalServer)(this.config.serverType, {basePath});
|
|
104
110
|
this.server = this.app.createHttpServer();
|
|
111
|
+
span.end();
|
|
105
112
|
}
|
|
106
113
|
setConfig(config) {
|
|
107
114
|
const {appConfig, runtimeEnvironment, globalData} = (0, import_config.loadConfig)(config);
|
|
@@ -113,6 +120,7 @@ var LwrApp = class {
|
|
|
113
120
|
return this.config;
|
|
114
121
|
}
|
|
115
122
|
async init() {
|
|
123
|
+
const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.InitServer});
|
|
116
124
|
if (this.initialized) {
|
|
117
125
|
return;
|
|
118
126
|
}
|
|
@@ -124,8 +132,10 @@ var LwrApp = class {
|
|
|
124
132
|
this.initialized = false;
|
|
125
133
|
throw e;
|
|
126
134
|
}
|
|
135
|
+
span.end();
|
|
127
136
|
}
|
|
128
137
|
async listen(callback) {
|
|
138
|
+
const span = (0, import_instrumentation.getTracer)().startSpan({name: import_instrumentation.CoreSpan.StartServer});
|
|
129
139
|
await this.init();
|
|
130
140
|
const {server, config, app} = this;
|
|
131
141
|
const {serverMode, port} = config;
|
|
@@ -152,6 +162,7 @@ var LwrApp = class {
|
|
|
152
162
|
}
|
|
153
163
|
const opts = {serverMode, port};
|
|
154
164
|
callback?.(opts);
|
|
165
|
+
span.end();
|
|
155
166
|
resolve(opts);
|
|
156
167
|
});
|
|
157
168
|
});
|
|
@@ -29,42 +29,64 @@ __export(exports, {
|
|
|
29
29
|
var import_path = __toModule(require("path"));
|
|
30
30
|
var import_identity = __toModule(require("./utils/identity.cjs"));
|
|
31
31
|
var import_error_handling = __toModule(require("./utils/error-handling.cjs"));
|
|
32
|
+
var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
32
33
|
function createAssetMiddleware(context) {
|
|
33
34
|
const {
|
|
34
35
|
assetRegistry,
|
|
35
36
|
runtimeEnvironment: {basePath}
|
|
36
37
|
} = context;
|
|
37
|
-
return async (req, res) => {
|
|
38
|
+
return async (req, res, next) => {
|
|
38
39
|
const {runtimeEnvironment} = req.getRuntimeContext(context.runtimeEnvironment);
|
|
39
40
|
const {assetId, immutable, signature} = (0, import_identity.getAssetIdentity)(req);
|
|
40
41
|
if (basePath && !assetId.specifier.startsWith(basePath)) {
|
|
41
42
|
assetId.specifier = import_path.default.join(basePath, assetId.specifier);
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
try {
|
|
45
|
+
const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
|
|
46
|
+
if (assetUri.external) {
|
|
47
|
+
res.set({
|
|
48
|
+
Location: assetUri.uri,
|
|
49
|
+
"cache-control": "public, max-age=60"
|
|
50
|
+
});
|
|
51
|
+
res.sendStatus(302);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const asset = await assetRegistry.getAsset({...assetId, signature}, runtimeEnvironment, req.isSiteGeneration());
|
|
55
|
+
if (req.isSiteGeneration()) {
|
|
56
|
+
res.setSiteGenerationMetadata({asset});
|
|
57
|
+
}
|
|
58
|
+
if (asset.mime) {
|
|
59
|
+
res.type(asset.mime);
|
|
60
|
+
}
|
|
61
|
+
if (runtimeEnvironment.immutableAssets && immutable) {
|
|
62
|
+
res.setHeader("Cache-control", "public, max-age=12895706, immutable");
|
|
63
|
+
} else if (runtimeEnvironment.immutableAssets) {
|
|
64
|
+
res.setHeader("Cache-control", "public, max-age=60");
|
|
65
|
+
}
|
|
66
|
+
res.status(200).stream(asset.stream());
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (import_path.default.dirname(assetId.specifier) === (basePath ? basePath : "/") && error instanceof import_diagnostics.DiagnosticsError && error?.diagnostics[0]?.description.category === "lwrUnresolvable/asset") {
|
|
69
|
+
await next();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
51
73
|
}
|
|
52
|
-
const asset = await assetRegistry.getAsset({...assetId, signature}, runtimeEnvironment, req.isSiteGeneration());
|
|
53
|
-
if (req.isSiteGeneration()) {
|
|
54
|
-
res.setSiteGenerationMetadata({asset});
|
|
55
|
-
}
|
|
56
|
-
if (asset.mime) {
|
|
57
|
-
res.type(asset.mime);
|
|
58
|
-
}
|
|
59
|
-
if (runtimeEnvironment.immutableAssets && immutable) {
|
|
60
|
-
res.setHeader("Cache-control", "public, max-age=12895706, immutable");
|
|
61
|
-
} else if (runtimeEnvironment.immutableAssets) {
|
|
62
|
-
res.setHeader("Cache-control", "public, max-age=60");
|
|
63
|
-
}
|
|
64
|
-
res.status(200).stream(asset.stream());
|
|
65
74
|
};
|
|
66
75
|
}
|
|
67
76
|
function assetMiddleware(app, context) {
|
|
68
|
-
const paths = context.appConfig.assets.map((
|
|
69
|
-
|
|
77
|
+
const paths = context.appConfig.assets.map((config) => {
|
|
78
|
+
const assetDirConfig = config;
|
|
79
|
+
let urlPath = config.urlPath;
|
|
80
|
+
if (assetDirConfig.root) {
|
|
81
|
+
urlPath = "/:filename";
|
|
82
|
+
} else if (assetDirConfig.dir) {
|
|
83
|
+
urlPath += app.getRegexWildcard();
|
|
84
|
+
}
|
|
85
|
+
return urlPath;
|
|
86
|
+
});
|
|
87
|
+
app.get([
|
|
88
|
+
...[...new Set(paths)],
|
|
89
|
+
"/:apiVersion/:assetType(asset|content-asset)/:immutable?/s/:signature/" + app.getRegexWildcard(),
|
|
90
|
+
"/:apiVersion/:assetType(asset|content-asset)/:immutable?/" + app.getRegexWildcard()
|
|
91
|
+
], (0, import_error_handling.handleErrors)(createAssetMiddleware(context)));
|
|
70
92
|
}
|
|
@@ -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 =
|
|
78
|
+
const specifier = type ? "/" + 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)
|
|
@@ -71,6 +71,8 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
71
71
|
if (!errorRoute) {
|
|
72
72
|
throw err;
|
|
73
73
|
}
|
|
74
|
+
import_shared_utils.logger.error(`[view-middleware] Route Error ${req.originalUrl}`);
|
|
75
|
+
import_shared_utils.logger.error(err);
|
|
74
76
|
viewResponse = await resolve.call(viewHandler, viewRequest, errorRoute, runtimeEnvironment, runtimeParams);
|
|
75
77
|
resolvedRoute = errorRoute;
|
|
76
78
|
}
|
|
@@ -100,10 +102,12 @@ function createConfigMiddleware(routes, context, viewHandler) {
|
|
|
100
102
|
return;
|
|
101
103
|
}
|
|
102
104
|
const url = (0, import_shared_utils.decodeViewPath)(encodedViewPath);
|
|
105
|
+
const originalUrl = req.originalUrl;
|
|
103
106
|
const requestPath = route.path;
|
|
104
107
|
const params = (0, import_shared_utils.extractRequestParams)(requestPath, url, req.params);
|
|
105
108
|
const viewRequest = {
|
|
106
109
|
url,
|
|
110
|
+
originalUrl,
|
|
107
111
|
params,
|
|
108
112
|
query: req.query,
|
|
109
113
|
requestPath
|
|
@@ -29,6 +29,7 @@ __export(exports, {
|
|
|
29
29
|
});
|
|
30
30
|
var import_perf_hooks = __toModule(require("perf_hooks"));
|
|
31
31
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
32
|
+
var import_site_metadata = __toModule(require("@lwrjs/static/site-metadata"));
|
|
32
33
|
var import_path = __toModule(require("path"));
|
|
33
34
|
var import_fs_extra = __toModule(require("fs-extra"));
|
|
34
35
|
var import_stream = __toModule(require("./utils/stream.cjs"));
|
|
@@ -198,7 +199,8 @@ var SiteGenerator = class {
|
|
|
198
199
|
const specifier = resourceDefinition.specifier;
|
|
199
200
|
const resourceMetadata = {
|
|
200
201
|
path: decodeURIComponent(url),
|
|
201
|
-
mimeType: resourceDefinition.type
|
|
202
|
+
mimeType: resourceDefinition.type,
|
|
203
|
+
inline: resourceDefinition.inline
|
|
202
204
|
};
|
|
203
205
|
const siteResources = siteConfig.siteMetadata.getSiteResources();
|
|
204
206
|
siteResources.resources[specifier] = resourceMetadata;
|
|
@@ -366,7 +368,8 @@ var SiteGenerator = class {
|
|
|
366
368
|
const normalizedUrl = decodeURIComponent(url);
|
|
367
369
|
(0, import_dir.createResourceDir)((0, import_path.dirname)(normalizedUrl), outputDir);
|
|
368
370
|
const fullPath = (0, import_path.join)(outputDir, normalizedUrl);
|
|
369
|
-
|
|
371
|
+
const index = fullPath ? fullPath.indexOf("?") : -1;
|
|
372
|
+
return index !== -1 ? fullPath.substring(0, index) : fullPath;
|
|
370
373
|
}
|
|
371
374
|
writeNetlifyRedirectConfig(outputDir, urlRewriteMap) {
|
|
372
375
|
const serveJsonPath = (0, import_path.join)(outputDir, "serve.json");
|
|
@@ -393,10 +396,24 @@ var SiteGenerator = class {
|
|
|
393
396
|
try {
|
|
394
397
|
const assetSrcFile = asset.file;
|
|
395
398
|
const assetSrcDir = asset.dir;
|
|
396
|
-
const
|
|
399
|
+
const isRootConfig = asset.root;
|
|
400
|
+
const urlPath = asset.urlPath;
|
|
401
|
+
const assetsPath = (0, import_path.join)(outputDir, basePath ? basePath + urlPath : urlPath);
|
|
397
402
|
if (assetSrcDir && import_fs_extra.default.existsSync(assetSrcDir)) {
|
|
398
|
-
|
|
399
|
-
|
|
403
|
+
if (isRootConfig) {
|
|
404
|
+
const files = import_fs_extra.default.readdirSync(assetSrcDir);
|
|
405
|
+
for (const file of files) {
|
|
406
|
+
const filePath = (0, import_path.join)(assetSrcDir, file);
|
|
407
|
+
if (import_fs_extra.default.statSync(filePath).isFile()) {
|
|
408
|
+
const fileDestPath = (0, import_path.join)(assetsPath, file);
|
|
409
|
+
import_fs_extra.default.copySync(filePath, fileDestPath);
|
|
410
|
+
this.addAssetToMetadata(fileDestPath, siteConfig);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
} else {
|
|
414
|
+
import_fs_extra.default.copySync(assetSrcDir, assetsPath);
|
|
415
|
+
this.addAssetsToMetadata(assetsPath, siteConfig);
|
|
416
|
+
}
|
|
400
417
|
} else if (assetSrcFile && import_fs_extra.default.existsSync(assetSrcFile)) {
|
|
401
418
|
import_fs_extra.default.copySync(assetSrcFile, assetsPath);
|
|
402
419
|
this.addAssetToMetadata(assetsPath, siteConfig);
|
|
@@ -404,7 +421,8 @@ var SiteGenerator = class {
|
|
|
404
421
|
import_shared_utils.logger.warn("[SSG] Could not find assets to copy at path: " + assetsPath);
|
|
405
422
|
}
|
|
406
423
|
} catch (e) {
|
|
407
|
-
import_shared_utils.logger.error("[SSG] Error occurred processing asset config: " + JSON.stringify(asset)
|
|
424
|
+
import_shared_utils.logger.error("[SSG] Error occurred processing asset config: " + JSON.stringify(asset));
|
|
425
|
+
import_shared_utils.logger.error(e);
|
|
408
426
|
}
|
|
409
427
|
}
|
|
410
428
|
await siteConfig.siteMetadata?.persistSiteMetadata();
|
|
@@ -462,7 +480,7 @@ var SiteGenerator = class {
|
|
|
462
480
|
endpoints,
|
|
463
481
|
skipBaseDocumentGeneration,
|
|
464
482
|
...featureFlags,
|
|
465
|
-
siteMetadata: new
|
|
483
|
+
siteMetadata: new import_site_metadata.SiteMetadataImpl({rootDir: outputDir})
|
|
466
484
|
};
|
|
467
485
|
}
|
|
468
486
|
filterFeatureFlags() {
|
package/build/es/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getFeatureFlags, DEFAULT_LWR_BOOTSTRAP_CONFIG, logger } from '@lwrjs/shared-utils';
|
|
2
2
|
import { createInternalServer } from '@lwrjs/server';
|
|
3
3
|
import { LwrServerError, createSingleDiagnosticError, descriptions } from '@lwrjs/diagnostics';
|
|
4
|
-
import { loadConfig, executeConfigHooks, executeStartHooks } from '@lwrjs/config';
|
|
4
|
+
import { loadConfig, executeConfigHooks, executeStartHooks, executeInstrumentationHooks, } 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';
|
|
@@ -15,6 +15,7 @@ import { assetMiddleware } from './middleware/asset-middleware.js';
|
|
|
15
15
|
import { viewMiddleware } from './middleware/view-middleware.js';
|
|
16
16
|
import { resourceMiddleware } from './middleware/resource-middleware.js';
|
|
17
17
|
import { hmrMiddleware } from './middleware/hmr-middleware.js';
|
|
18
|
+
import { getTracer, CoreSpan } from '@lwrjs/instrumentation';
|
|
18
19
|
function initMiddleware(app, server, serverContext) {
|
|
19
20
|
// all middleware attached AFTER compression will have compressed responses
|
|
20
21
|
app.useCompression();
|
|
@@ -44,12 +45,13 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
44
45
|
if (hooks.length) {
|
|
45
46
|
const skipValidation = true; // skip for config hook, since `executeStartHooks` hook will validate
|
|
46
47
|
await executeConfigHooks(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
|
|
48
|
+
executeInstrumentationHooks(hooks);
|
|
47
49
|
executeStartHooks(hooks, appConfig);
|
|
48
50
|
}
|
|
49
51
|
// load all configurable modules
|
|
50
52
|
const services = await loadServices(appConfig);
|
|
51
53
|
// create all framework components(ie. registries)
|
|
52
|
-
const serverContext = createServerContext(appConfig, runtimeEnvironment, globalData);
|
|
54
|
+
const serverContext = getTracer().trace({ name: CoreSpan.CreateServerContext }, () => createServerContext(appConfig, runtimeEnvironment, globalData));
|
|
53
55
|
// create public subset of configurations
|
|
54
56
|
const providerContext = createProviderContext(serverContext);
|
|
55
57
|
const { moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler } = serverContext;
|
|
@@ -61,14 +63,22 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
61
63
|
const viewProviders = createServices(services.viewProviders, providerContext);
|
|
62
64
|
const viewTransformers = createServices(services.viewTransformers, providerContext);
|
|
63
65
|
const bundleProviders = createServices(services.bundleProviders, providerContext);
|
|
66
|
+
const uriTransformers = createServices(services.uriTransformers, providerContext);
|
|
64
67
|
// add services to their corresponding registry
|
|
65
|
-
|
|
68
|
+
// Assets
|
|
66
69
|
assetRegistry.addAssetProviders(assetProviders);
|
|
67
|
-
assetRegistry.addAssetTransformers(assetTransformers);
|
|
70
|
+
assetRegistry.addAssetTransformers([...assetTransformers, ...uriTransformers]);
|
|
71
|
+
// Bundles
|
|
72
|
+
moduleBundler.addBundleProviders(bundleProviders);
|
|
73
|
+
moduleBundler.addBundleTransformers(uriTransformers);
|
|
74
|
+
// Modules
|
|
75
|
+
moduleRegistry.addModuleProviders(moduleProviders);
|
|
76
|
+
// Resources
|
|
68
77
|
resourceRegistry.addResourceProviders(resourceProviders);
|
|
78
|
+
resourceRegistry.addResourceTransformers(uriTransformers);
|
|
79
|
+
// Views
|
|
69
80
|
viewRegistry.addViewProviders(viewProviders);
|
|
70
81
|
viewRegistry.addViewTransformers(viewTransformers);
|
|
71
|
-
moduleBundler.addBundleProviders(bundleProviders);
|
|
72
82
|
// invoke async initialization
|
|
73
83
|
await serverContext.viewRegistry.initializeViewProviders();
|
|
74
84
|
// set routes on server context
|
|
@@ -79,6 +89,7 @@ async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
|
79
89
|
export class LwrApp {
|
|
80
90
|
constructor(config = {}) {
|
|
81
91
|
this.initialized = false;
|
|
92
|
+
const span = getTracer().startSpan({ name: CoreSpan.CreateServer });
|
|
82
93
|
const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
|
|
83
94
|
this.config = appConfig;
|
|
84
95
|
this.runtimeEnvironment = runtimeEnvironment;
|
|
@@ -86,6 +97,7 @@ export class LwrApp {
|
|
|
86
97
|
const { basePath } = this.config;
|
|
87
98
|
this.app = createInternalServer(this.config.serverType, { basePath });
|
|
88
99
|
this.server = this.app.createHttpServer();
|
|
100
|
+
span.end();
|
|
89
101
|
}
|
|
90
102
|
setConfig(config) {
|
|
91
103
|
const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
|
|
@@ -97,6 +109,7 @@ export class LwrApp {
|
|
|
97
109
|
return this.config;
|
|
98
110
|
}
|
|
99
111
|
async init() {
|
|
112
|
+
const span = getTracer().startSpan({ name: CoreSpan.InitServer });
|
|
100
113
|
if (this.initialized) {
|
|
101
114
|
return;
|
|
102
115
|
}
|
|
@@ -113,8 +126,10 @@ export class LwrApp {
|
|
|
113
126
|
this.initialized = false;
|
|
114
127
|
throw e;
|
|
115
128
|
}
|
|
129
|
+
span.end();
|
|
116
130
|
}
|
|
117
131
|
async listen(callback) {
|
|
132
|
+
const span = getTracer().startSpan({ name: CoreSpan.StartServer });
|
|
118
133
|
await this.init();
|
|
119
134
|
const { server, config, app } = this;
|
|
120
135
|
const { serverMode, port } = config;
|
|
@@ -142,6 +157,7 @@ export class LwrApp {
|
|
|
142
157
|
}
|
|
143
158
|
const opts = { serverMode, port };
|
|
144
159
|
callback?.(opts);
|
|
160
|
+
span.end(); // TODO is this the right tracing for start server?
|
|
145
161
|
resolve(opts);
|
|
146
162
|
});
|
|
147
163
|
});
|
|
@@ -1,42 +1,73 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import { getAssetIdentity } from './utils/identity.js';
|
|
3
3
|
import { handleErrors } from './utils/error-handling.js';
|
|
4
|
+
import { DiagnosticsError } from '@lwrjs/diagnostics';
|
|
4
5
|
function createAssetMiddleware(context) {
|
|
5
6
|
const { assetRegistry, runtimeEnvironment: { basePath }, } = context;
|
|
6
|
-
return async (req, res) => {
|
|
7
|
+
return async (req, res, next) => {
|
|
7
8
|
const { runtimeEnvironment } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
8
9
|
const { assetId, immutable, signature } = getAssetIdentity(req);
|
|
9
10
|
if (basePath && !assetId.specifier.startsWith(basePath)) {
|
|
10
11
|
assetId.specifier = path.join(basePath, assetId.specifier);
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
13
|
+
try {
|
|
14
|
+
// Redirect if this is an external asset
|
|
15
|
+
const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
|
|
16
|
+
if (assetUri.external) {
|
|
17
|
+
res.set({
|
|
18
|
+
Location: assetUri.uri,
|
|
19
|
+
'cache-control': 'public, max-age=60',
|
|
20
|
+
});
|
|
21
|
+
res.sendStatus(302);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const asset = await assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
|
|
25
|
+
if (req.isSiteGeneration()) {
|
|
26
|
+
res.setSiteGenerationMetadata({ asset });
|
|
27
|
+
}
|
|
28
|
+
if (asset.mime) {
|
|
29
|
+
res.type(asset.mime);
|
|
30
|
+
}
|
|
31
|
+
if (runtimeEnvironment.immutableAssets && immutable) {
|
|
32
|
+
res.setHeader('Cache-control', 'public, max-age=12895706, immutable');
|
|
33
|
+
}
|
|
34
|
+
else if (runtimeEnvironment.immutableAssets) {
|
|
35
|
+
res.setHeader('Cache-control', 'public, max-age=60');
|
|
36
|
+
}
|
|
37
|
+
res.status(200).stream(asset.stream());
|
|
21
38
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
39
|
+
catch (error) {
|
|
40
|
+
// Ignore asset not found for root asset requests
|
|
41
|
+
if (path.dirname(assetId.specifier) === (basePath ? basePath : '/') &&
|
|
42
|
+
error instanceof DiagnosticsError &&
|
|
43
|
+
error?.diagnostics[0]?.description.category === 'lwrUnresolvable/asset') {
|
|
44
|
+
// Must await other middleware or this can respond before expected.
|
|
45
|
+
await next();
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// else throw the error
|
|
49
|
+
throw error;
|
|
25
50
|
}
|
|
26
|
-
if (asset.mime) {
|
|
27
|
-
res.type(asset.mime);
|
|
28
|
-
}
|
|
29
|
-
if (runtimeEnvironment.immutableAssets && immutable) {
|
|
30
|
-
res.setHeader('Cache-control', 'public, max-age=12895706, immutable');
|
|
31
|
-
}
|
|
32
|
-
else if (runtimeEnvironment.immutableAssets) {
|
|
33
|
-
res.setHeader('Cache-control', 'public, max-age=60');
|
|
34
|
-
}
|
|
35
|
-
res.status(200).stream(asset.stream());
|
|
36
51
|
};
|
|
37
52
|
}
|
|
38
53
|
export function assetMiddleware(app, context) {
|
|
39
|
-
const paths = context.appConfig.assets.map((
|
|
40
|
-
|
|
54
|
+
const paths = context.appConfig.assets.map((config) => {
|
|
55
|
+
const assetDirConfig = config;
|
|
56
|
+
let urlPath = config.urlPath;
|
|
57
|
+
// 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.
|
|
58
|
+
if (assetDirConfig.root) {
|
|
59
|
+
urlPath = '/:filename';
|
|
60
|
+
}
|
|
61
|
+
else if (assetDirConfig.dir) {
|
|
62
|
+
urlPath += app.getRegexWildcard();
|
|
63
|
+
}
|
|
64
|
+
return urlPath;
|
|
65
|
+
});
|
|
66
|
+
app.get([
|
|
67
|
+
// De-dupe paths (i.e. root path may have been added more than once)
|
|
68
|
+
...[...new Set(paths)],
|
|
69
|
+
'/:apiVersion/:assetType(asset|content-asset)/:immutable?/s/:signature/' + app.getRegexWildcard(),
|
|
70
|
+
'/:apiVersion/:assetType(asset|content-asset)/:immutable?/' + app.getRegexWildcard(),
|
|
71
|
+
], handleErrors(createAssetMiddleware(context)));
|
|
41
72
|
}
|
|
42
73
|
//# sourceMappingURL=asset-middleware.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import type { ServerContext } from '@lwrjs/types';
|
|
3
|
-
import http from 'http';
|
|
3
|
+
import type http from 'http';
|
|
4
4
|
export declare function hmrMiddleware(server: http.Server, context: ServerContext): void;
|
|
5
5
|
//# sourceMappingURL=hmr-middleware.d.ts.map
|
|
@@ -44,7 +44,7 @@ export function getResourceIdentity(req) {
|
|
|
44
44
|
}
|
|
45
45
|
export function getAssetIdentity(req) {
|
|
46
46
|
const { signature, immutable, assetType: type } = req.params;
|
|
47
|
-
const specifier =
|
|
47
|
+
const specifier = type ? '/' + req.params[0] : req.originalUrl.split('?')[0];
|
|
48
48
|
if (validateSpecifier(specifier) === false) {
|
|
49
49
|
throw createSingleDiagnosticError({
|
|
50
50
|
description: descriptions.UNRESOLVABLE.INVALID_SPECIFIER(specifier),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { descriptions } from '@lwrjs/diagnostics';
|
|
2
2
|
import { getClientRoutes } from '@lwrjs/router';
|
|
3
|
-
import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, shortestTtl, } from '@lwrjs/shared-utils';
|
|
3
|
+
import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, logger, shortestTtl, } from '@lwrjs/shared-utils';
|
|
4
4
|
import { handleErrors } from './utils/error-handling.js';
|
|
5
5
|
import { LwrViewHandler } from '@lwrjs/view-registry';
|
|
6
6
|
const CANONICAL_VIEW_ROUTES = [
|
|
@@ -45,6 +45,9 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
45
45
|
if (!errorRoute) {
|
|
46
46
|
throw err;
|
|
47
47
|
}
|
|
48
|
+
// Log Unexpected Routing Errors
|
|
49
|
+
logger.error(`[view-middleware] Route Error ${req.originalUrl}`);
|
|
50
|
+
logger.error(err);
|
|
48
51
|
viewResponse = await resolve.call(viewHandler, viewRequest, errorRoute, runtimeEnvironment, runtimeParams);
|
|
49
52
|
resolvedRoute = errorRoute;
|
|
50
53
|
}
|
|
@@ -79,10 +82,12 @@ function createConfigMiddleware(routes, context, viewHandler) {
|
|
|
79
82
|
}
|
|
80
83
|
// decode the resolved view path and extract any params.
|
|
81
84
|
const url = decodeViewPath(encodedViewPath);
|
|
85
|
+
const originalUrl = req.originalUrl;
|
|
82
86
|
const requestPath = route.path;
|
|
83
87
|
const params = extractRequestParams(requestPath, url, req.params);
|
|
84
88
|
const viewRequest = {
|
|
85
89
|
url,
|
|
90
|
+
originalUrl,
|
|
86
91
|
params,
|
|
87
92
|
query: req.query,
|
|
88
93
|
requestPath,
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { NormalizedLwrGlobalConfig } from '@lwrjs/types';
|
|
1
|
+
import type { NormalizedLwrGlobalConfig } from '@lwrjs/types';
|
|
2
2
|
export declare function warmupServer(config: NormalizedLwrGlobalConfig, internalRequestKey: string): Promise<void>;
|
|
3
3
|
//# sourceMappingURL=server-warmup.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ImportMetadata, LwrDispatcher, StaticSiteGenerator, LwrRoute, NormalizedLwrGlobalConfig, RuntimeEnvironment } from '@lwrjs/types';
|
|
2
|
-
import { ResourceContextOpts, SiteConfig, ViewImportMetadata } from './types.js';
|
|
2
|
+
import type { ResourceContextOpts, SiteConfig, ViewImportMetadata } from './types.js';
|
|
3
3
|
export default class SiteGenerator {
|
|
4
4
|
/**
|
|
5
5
|
* Build a static site in the configured directory
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { performance } from 'perf_hooks';
|
|
2
|
-
import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, logger, WARN, INFO,
|
|
2
|
+
import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, logger, WARN, INFO, isExternalUrl, mimeLookup, } from '@lwrjs/shared-utils';
|
|
3
|
+
import { SiteMetadataImpl } from '@lwrjs/static/site-metadata';
|
|
3
4
|
import { join, dirname, extname, normalize } from 'path';
|
|
4
5
|
import fs from 'fs-extra';
|
|
5
6
|
import { writeResponse } from './utils/stream.js';
|
|
@@ -254,6 +255,7 @@ export default class SiteGenerator {
|
|
|
254
255
|
const resourceMetadata = {
|
|
255
256
|
path: decodeURIComponent(url),
|
|
256
257
|
mimeType: resourceDefinition.type,
|
|
258
|
+
inline: resourceDefinition.inline,
|
|
257
259
|
};
|
|
258
260
|
const siteResources = siteConfig.siteMetadata.getSiteResources();
|
|
259
261
|
siteResources.resources[specifier] = resourceMetadata;
|
|
@@ -502,7 +504,9 @@ export default class SiteGenerator {
|
|
|
502
504
|
const normalizedUrl = decodeURIComponent(url);
|
|
503
505
|
createResourceDir(dirname(normalizedUrl), outputDir);
|
|
504
506
|
const fullPath = join(outputDir, normalizedUrl);
|
|
505
|
-
|
|
507
|
+
// Remove query params from file paths
|
|
508
|
+
const index = fullPath ? fullPath.indexOf('?') : -1;
|
|
509
|
+
return index !== -1 ? fullPath.substring(0, index) : fullPath;
|
|
506
510
|
}
|
|
507
511
|
/**
|
|
508
512
|
* Write out redirect mapping files for static hosting services like netlify. Examples for why this is needed:
|
|
@@ -550,10 +554,27 @@ export default class SiteGenerator {
|
|
|
550
554
|
try {
|
|
551
555
|
const assetSrcFile = asset.file;
|
|
552
556
|
const assetSrcDir = asset.dir;
|
|
553
|
-
const
|
|
557
|
+
const isRootConfig = asset.root;
|
|
558
|
+
const urlPath = asset.urlPath;
|
|
559
|
+
const assetsPath = join(outputDir, basePath ? basePath + urlPath : urlPath);
|
|
554
560
|
if (assetSrcDir && fs.existsSync(assetSrcDir)) {
|
|
555
|
-
|
|
556
|
-
|
|
561
|
+
// If this is a root folder we do not want to recurse sub directories.
|
|
562
|
+
if (isRootConfig) {
|
|
563
|
+
const files = fs.readdirSync(assetSrcDir);
|
|
564
|
+
for (const file of files) {
|
|
565
|
+
const filePath = join(assetSrcDir, file);
|
|
566
|
+
if (fs.statSync(filePath).isFile()) {
|
|
567
|
+
const fileDestPath = join(assetsPath, file);
|
|
568
|
+
fs.copySync(filePath, fileDestPath);
|
|
569
|
+
this.addAssetToMetadata(fileDestPath, siteConfig);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
// else copy the source to the ssg root and then add the ssg paths to the metadata
|
|
575
|
+
fs.copySync(assetSrcDir, assetsPath);
|
|
576
|
+
this.addAssetsToMetadata(assetsPath, siteConfig);
|
|
577
|
+
}
|
|
557
578
|
}
|
|
558
579
|
else if (assetSrcFile && fs.existsSync(assetSrcFile)) {
|
|
559
580
|
fs.copySync(assetSrcFile, assetsPath);
|
|
@@ -564,7 +585,8 @@ export default class SiteGenerator {
|
|
|
564
585
|
}
|
|
565
586
|
}
|
|
566
587
|
catch (e) {
|
|
567
|
-
logger.error('[SSG] Error occurred processing asset config: ' + JSON.stringify(asset)
|
|
588
|
+
logger.error('[SSG] Error occurred processing asset config: ' + JSON.stringify(asset));
|
|
589
|
+
logger.error(e);
|
|
568
590
|
}
|
|
569
591
|
}
|
|
570
592
|
await siteConfig.siteMetadata?.persistSiteMetadata();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
import http from 'http';
|
|
3
|
-
import { LwrDispatcher, FsContext } from '@lwrjs/types';
|
|
3
|
+
import type { LwrDispatcher, FsContext } from '@lwrjs/types';
|
|
4
4
|
export default class NetworkDispatcher implements LwrDispatcher {
|
|
5
5
|
port: number;
|
|
6
6
|
internalRequestKey: string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { Readable } from 'stream';
|
|
3
|
-
import { FsContext } from '@lwrjs/types';
|
|
2
|
+
import type { Readable } from 'stream';
|
|
3
|
+
import type { FsContext } from '@lwrjs/types';
|
|
4
4
|
export declare function writeStream(readStream: Readable, fullPath: string): Promise<void>;
|
|
5
5
|
export declare function writeResponse(context: FsContext, fullPath: string): Promise<void>;
|
|
6
6
|
/**
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.
|
|
7
|
+
"version": "0.11.0-alpha.0",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -35,48 +35,55 @@
|
|
|
35
35
|
"build/**/*.d.ts",
|
|
36
36
|
"package.cjs"
|
|
37
37
|
],
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc -b"
|
|
40
|
+
},
|
|
38
41
|
"dependencies": {
|
|
39
|
-
"@
|
|
40
|
-
"@lwrjs/
|
|
41
|
-
"@lwrjs/asset-
|
|
42
|
-
"@lwrjs/
|
|
43
|
-
"@lwrjs/base-view-
|
|
44
|
-
"@lwrjs/
|
|
45
|
-
"@lwrjs/
|
|
46
|
-
"@lwrjs/
|
|
47
|
-
"@lwrjs/
|
|
48
|
-
"@lwrjs/
|
|
49
|
-
"@lwrjs/
|
|
50
|
-
"@lwrjs/loader": "0.
|
|
51
|
-
"@lwrjs/lwc-module-provider": "0.
|
|
52
|
-
"@lwrjs/markdown-view-provider": "0.
|
|
53
|
-
"@lwrjs/module-bundler": "0.
|
|
54
|
-
"@lwrjs/module-registry": "0.
|
|
55
|
-
"@lwrjs/npm-module-provider": "0.
|
|
56
|
-
"@lwrjs/nunjucks-view-provider": "0.
|
|
57
|
-
"@lwrjs/o11y": "0.
|
|
58
|
-
"@lwrjs/resource-registry": "0.
|
|
59
|
-
"@lwrjs/router": "0.
|
|
60
|
-
"@lwrjs/server": "0.
|
|
61
|
-
"@lwrjs/shared-utils": "0.
|
|
62
|
-
"@lwrjs/
|
|
42
|
+
"@lwrjs/app-service": "0.11.0-alpha.0",
|
|
43
|
+
"@lwrjs/asset-registry": "0.11.0-alpha.0",
|
|
44
|
+
"@lwrjs/asset-transformer": "0.11.0-alpha.0",
|
|
45
|
+
"@lwrjs/base-view-provider": "0.11.0-alpha.0",
|
|
46
|
+
"@lwrjs/base-view-transformer": "0.11.0-alpha.0",
|
|
47
|
+
"@lwrjs/client-modules": "0.11.0-alpha.0",
|
|
48
|
+
"@lwrjs/config": "0.11.0-alpha.0",
|
|
49
|
+
"@lwrjs/diagnostics": "0.11.0-alpha.0",
|
|
50
|
+
"@lwrjs/fs-asset-provider": "0.11.0-alpha.0",
|
|
51
|
+
"@lwrjs/html-view-provider": "0.11.0-alpha.0",
|
|
52
|
+
"@lwrjs/instrumentation": "0.11.0-alpha.0",
|
|
53
|
+
"@lwrjs/loader": "0.11.0-alpha.0",
|
|
54
|
+
"@lwrjs/lwc-module-provider": "0.11.0-alpha.0",
|
|
55
|
+
"@lwrjs/markdown-view-provider": "0.11.0-alpha.0",
|
|
56
|
+
"@lwrjs/module-bundler": "0.11.0-alpha.0",
|
|
57
|
+
"@lwrjs/module-registry": "0.11.0-alpha.0",
|
|
58
|
+
"@lwrjs/npm-module-provider": "0.11.0-alpha.0",
|
|
59
|
+
"@lwrjs/nunjucks-view-provider": "0.11.0-alpha.0",
|
|
60
|
+
"@lwrjs/o11y": "0.11.0-alpha.0",
|
|
61
|
+
"@lwrjs/resource-registry": "0.11.0-alpha.0",
|
|
62
|
+
"@lwrjs/router": "0.11.0-alpha.0",
|
|
63
|
+
"@lwrjs/server": "0.11.0-alpha.0",
|
|
64
|
+
"@lwrjs/shared-utils": "0.11.0-alpha.0",
|
|
65
|
+
"@lwrjs/static": "0.11.0-alpha.0",
|
|
66
|
+
"@lwrjs/view-registry": "0.11.0-alpha.0",
|
|
63
67
|
"chokidar": "^3.5.3",
|
|
64
68
|
"esbuild": "^0.9.7",
|
|
65
|
-
"fs-extra": "^11.1.
|
|
69
|
+
"fs-extra": "^11.1.1",
|
|
66
70
|
"path-to-regexp": "^6.2.0",
|
|
67
|
-
"qs": "^6.
|
|
71
|
+
"qs": "^6.11.2",
|
|
68
72
|
"rollup": "^2.78.0",
|
|
69
73
|
"ws": "^8.8.1"
|
|
70
74
|
},
|
|
71
75
|
"devDependencies": {
|
|
72
|
-
"@lwrjs/types": "0.
|
|
76
|
+
"@lwrjs/types": "0.11.0-alpha.0",
|
|
73
77
|
"@types/ws": "^8.5.3"
|
|
74
78
|
},
|
|
75
79
|
"peerDependencies": {
|
|
76
|
-
"lwc": "2.x"
|
|
80
|
+
"lwc": "2.x || 3.x"
|
|
77
81
|
},
|
|
78
82
|
"engines": {
|
|
79
|
-
"node": ">=16.0.0
|
|
83
|
+
"node": ">=16.0.0"
|
|
84
|
+
},
|
|
85
|
+
"volta": {
|
|
86
|
+
"extends": "../../../package.json"
|
|
80
87
|
},
|
|
81
|
-
"gitHead": "
|
|
88
|
+
"gitHead": "6917abefe32752eeed0f9ba98505ca2b76f1df9d"
|
|
82
89
|
}
|