@lwrjs/core 0.9.0-alpha.9 → 0.9.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 +9 -5
- package/build/cjs/context/server.cjs +6 -6
- package/build/cjs/index.cjs +66 -41
- package/build/cjs/middleware/asset-middleware.cjs +70 -0
- package/build/cjs/middleware/bundle-middleware.cjs +113 -0
- package/build/cjs/{middlewares → middleware}/hmr-middleware.cjs +6 -6
- package/build/cjs/{middlewares → middleware}/locale-middleware.cjs +2 -2
- package/build/cjs/middleware/mapping-middleware.cjs +61 -0
- package/build/cjs/middleware/module-middleware.cjs +88 -0
- package/build/cjs/middleware/redirects/unsigned-module-redirect.cjs +37 -0
- package/build/cjs/middleware/resource-middleware.cjs +64 -0
- package/build/cjs/{context/global-data.cjs → middleware/utils/error-handling.cjs} +26 -24
- package/build/cjs/middleware/utils/identity.cjs +92 -0
- package/build/cjs/{context/services.cjs → middleware/utils/metadata.cjs} +19 -20
- package/build/cjs/{middlewares/utils.cjs → middleware/utils/request.cjs} +17 -16
- package/build/cjs/middleware/view-middleware.cjs +151 -0
- package/build/cjs/middleware.cjs +16 -9
- package/build/cjs/tools/server-warmup.cjs +2 -9
- package/build/cjs/tools/static-generation.cjs +190 -62
- package/build/es/context/provider.js +5 -3
- package/build/es/context/server.d.ts +1 -1
- package/build/es/context/server.js +6 -5
- package/build/es/index.d.ts +3 -2
- package/build/es/index.js +85 -49
- package/build/es/middleware/asset-middleware.d.ts +3 -0
- package/build/es/middleware/asset-middleware.js +42 -0
- package/build/es/middleware/bundle-middleware.d.ts +3 -0
- package/build/es/middleware/bundle-middleware.js +88 -0
- package/build/es/middleware/hmr-middleware.d.ts +5 -0
- package/build/es/{middlewares → middleware}/hmr-middleware.js +4 -4
- package/build/es/middleware/locale-middleware.d.ts +3 -0
- package/build/es/{middlewares → middleware}/locale-middleware.js +2 -1
- package/build/es/middleware/mapping-middleware.d.ts +3 -0
- package/build/es/middleware/mapping-middleware.js +34 -0
- package/build/es/middleware/module-middleware.d.ts +3 -0
- package/build/es/middleware/module-middleware.js +64 -0
- package/build/es/middleware/redirects/unsigned-module-redirect.d.ts +6 -0
- package/build/es/middleware/redirects/unsigned-module-redirect.js +25 -0
- package/build/es/middleware/resource-middleware.d.ts +3 -0
- package/build/es/middleware/resource-middleware.js +37 -0
- package/build/es/middleware/utils/error-handling.d.ts +3 -0
- package/build/es/middleware/utils/error-handling.js +32 -0
- package/build/es/middleware/utils/identity.d.ts +6 -0
- package/build/es/middleware/utils/identity.js +62 -0
- package/build/es/middleware/utils/metadata.d.ts +3 -0
- package/build/es/middleware/utils/metadata.js +24 -0
- package/build/es/middleware/utils/request.d.ts +15 -0
- package/build/es/{middlewares/utils.js → middleware/utils/request.js} +15 -23
- package/build/es/middleware/view-middleware.d.ts +3 -0
- package/build/es/middleware/view-middleware.js +136 -0
- package/build/es/middleware.d.ts +8 -14
- package/build/es/middleware.js +12 -20
- package/build/es/tools/server-warmup.js +3 -10
- package/build/es/tools/static-generation.d.ts +11 -1
- package/build/es/tools/static-generation.js +230 -79
- package/build/es/tools/types.d.ts +3 -2
- package/package.json +33 -34
- package/build/cjs/context/configurations.cjs +0 -82
- package/build/cjs/middlewares/api-middleware.cjs +0 -359
- package/build/cjs/middlewares/base-middleware.cjs +0 -15
- package/build/cjs/middlewares/ui-middleware.cjs +0 -183
- package/build/cjs/tools/server-build.cjs +0 -182
- package/build/es/context/configurations.d.ts +0 -9
- package/build/es/context/configurations.js +0 -53
- package/build/es/context/global-data.d.ts +0 -3
- package/build/es/context/global-data.js +0 -29
- package/build/es/context/services.d.ts +0 -3
- package/build/es/context/services.js +0 -27
- package/build/es/middlewares/api-middleware.d.ts +0 -3
- package/build/es/middlewares/api-middleware.js +0 -410
- package/build/es/middlewares/base-middleware.d.ts +0 -3
- package/build/es/middlewares/base-middleware.js +0 -4
- package/build/es/middlewares/hmr-middleware.d.ts +0 -5
- package/build/es/middlewares/locale-middleware.d.ts +0 -3
- package/build/es/middlewares/ui-middleware.d.ts +0 -3
- package/build/es/middlewares/ui-middleware.js +0 -186
- package/build/es/middlewares/utils.d.ts +0 -22
- package/build/es/tools/server-build.d.ts +0 -14
- package/build/es/tools/server-build.js +0 -182
package/build/es/index.js
CHANGED
|
@@ -1,80 +1,117 @@
|
|
|
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 {
|
|
5
|
-
import
|
|
6
|
-
import apiMiddleware from './middlewares/api-middleware.js';
|
|
7
|
-
import uiMiddleware from './middlewares/ui-middleware.js';
|
|
8
|
-
import hmrMiddleware from './middlewares/hmr-middleware.js';
|
|
9
|
-
import baseMiddleware from './middlewares/base-middleware.js';
|
|
10
|
-
import { getServices } from './context/services.js';
|
|
11
|
-
import { resolveConfigurations } from './context/configurations.js';
|
|
12
|
-
import { createProviderContext } from './context/provider.js';
|
|
13
|
-
import { createServerContext } from './context/server.js';
|
|
4
|
+
import { loadConfig, executeConfigHooks, executeStartHooks } from '@lwrjs/config';
|
|
5
|
+
import { loadHooks, loadServices, loadRouteHandlers } from '@lwrjs/config/modules';
|
|
14
6
|
import SiteGenerator from './tools/static-generation.js';
|
|
15
7
|
import { warmupServer } from './tools/server-warmup.js';
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
import { createServerContext } from './context/server.js';
|
|
9
|
+
import { createProviderContext } from './context/provider.js';
|
|
10
|
+
import { localeMiddleware } from './middleware/locale-middleware.js';
|
|
11
|
+
import { moduleMiddleware } from './middleware/module-middleware.js';
|
|
12
|
+
import { bundleMiddleware } from './middleware/bundle-middleware.js';
|
|
13
|
+
import { mappingMiddleware } from './middleware/mapping-middleware.js';
|
|
14
|
+
import { assetMiddleware } from './middleware/asset-middleware.js';
|
|
15
|
+
import { viewMiddleware } from './middleware/view-middleware.js';
|
|
16
|
+
import { resourceMiddleware } from './middleware/resource-middleware.js';
|
|
17
|
+
import { hmrMiddleware } from './middleware/hmr-middleware.js';
|
|
18
|
+
function initMiddleware(app, server, serverContext) {
|
|
19
|
+
// all middleware attached AFTER compression will have compressed responses
|
|
20
|
+
app.useCompression();
|
|
19
21
|
localeMiddleware(app, serverContext);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
+
moduleMiddleware(app, serverContext);
|
|
23
|
+
bundleMiddleware(app, serverContext);
|
|
24
|
+
mappingMiddleware(app, serverContext);
|
|
25
|
+
assetMiddleware(app, serverContext);
|
|
26
|
+
resourceMiddleware(app, serverContext);
|
|
27
|
+
// view middleware MUST be attached last because it contains a greedy middleware
|
|
28
|
+
// to handle unsupported routes
|
|
29
|
+
viewMiddleware(app, serverContext);
|
|
30
|
+
// initialize routes MUST be called when using koa
|
|
31
|
+
app.initRoutes();
|
|
32
|
+
// hmr uses web sockets, so it doesn't matter when this is attached
|
|
22
33
|
if (serverContext.runtimeEnvironment.hmrEnabled) {
|
|
23
|
-
// setup hmr middleware
|
|
24
34
|
hmrMiddleware(server, serverContext);
|
|
25
35
|
}
|
|
26
36
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
function createServices(entries, providerContext) {
|
|
38
|
+
return entries.map(([ctor, providerConfig = {}]) => new ctor(providerConfig, providerContext));
|
|
39
|
+
}
|
|
40
|
+
async function initContext(appConfig, runtimeEnvironment, globalData) {
|
|
41
|
+
// load all hooks
|
|
42
|
+
const hooks = await loadHooks(appConfig);
|
|
43
|
+
// apply both config and on start hooks
|
|
44
|
+
if (hooks.length) {
|
|
45
|
+
const skipValidation = true; // skip for config hook, since `executeStartHooks` hook will validate
|
|
46
|
+
await executeConfigHooks(hooks, appConfig, runtimeEnvironment, globalData, skipValidation);
|
|
47
|
+
executeStartHooks(hooks, appConfig);
|
|
48
|
+
}
|
|
49
|
+
// load all configurable modules
|
|
50
|
+
const services = await loadServices(appConfig);
|
|
51
|
+
// create all framework components(ie. registries)
|
|
30
52
|
const serverContext = createServerContext(appConfig, runtimeEnvironment, globalData);
|
|
53
|
+
// create public subset of configurations
|
|
31
54
|
const providerContext = createProviderContext(serverContext);
|
|
32
|
-
const { moduleRegistry, resourceRegistry, viewRegistry,
|
|
33
|
-
//
|
|
34
|
-
const moduleProviders =
|
|
55
|
+
const { moduleRegistry, assetRegistry, resourceRegistry, viewRegistry, moduleBundler } = serverContext;
|
|
56
|
+
// instantiate each service
|
|
57
|
+
const moduleProviders = createServices(services.moduleProviders, providerContext);
|
|
58
|
+
const assetProviders = createServices(services.assetProviders, providerContext);
|
|
59
|
+
const assetTransformers = createServices(services.assetTransformers, providerContext);
|
|
60
|
+
const resourceProviders = createServices(services.resourceProviders, providerContext);
|
|
61
|
+
const viewProviders = createServices(services.viewProviders, providerContext);
|
|
62
|
+
const viewTransformers = createServices(services.viewTransformers, providerContext);
|
|
63
|
+
const bundleProviders = createServices(services.bundleProviders, providerContext);
|
|
64
|
+
// add services to their corresponding registry
|
|
35
65
|
moduleRegistry.addModuleProviders(moduleProviders);
|
|
36
|
-
|
|
37
|
-
|
|
66
|
+
assetRegistry.addAssetProviders(assetProviders);
|
|
67
|
+
assetRegistry.addAssetTransformers(assetTransformers);
|
|
38
68
|
resourceRegistry.addResourceProviders(resourceProviders);
|
|
39
|
-
// View Providers
|
|
40
|
-
const viewProviders = await getServices(appConfig.viewProviders, providerContext, appConfig);
|
|
41
|
-
// View Transformers
|
|
42
|
-
const viewTransformers = await getServices(appConfig.viewTransformers, providerContext, rawAppConfig);
|
|
43
69
|
viewRegistry.addViewProviders(viewProviders);
|
|
44
70
|
viewRegistry.addViewTransformers(viewTransformers);
|
|
45
|
-
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
moduleBundler.addBundleProviders(bundleProviders);
|
|
72
|
+
// invoke async initialization
|
|
73
|
+
await serverContext.viewRegistry.initializeViewProviders();
|
|
74
|
+
// set routes on server context
|
|
75
|
+
const routeHandlers = await loadRouteHandlers(appConfig);
|
|
76
|
+
serverContext.routeHandlers = routeHandlers;
|
|
51
77
|
return serverContext;
|
|
52
78
|
}
|
|
53
79
|
export class LwrApp {
|
|
54
|
-
constructor(config) {
|
|
80
|
+
constructor(config = {}) {
|
|
55
81
|
this.initialized = false;
|
|
56
|
-
|
|
82
|
+
const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
|
|
83
|
+
this.config = appConfig;
|
|
84
|
+
this.runtimeEnvironment = runtimeEnvironment;
|
|
85
|
+
this.globalData = globalData;
|
|
57
86
|
const { basePath } = this.config;
|
|
58
87
|
this.app = createInternalServer(this.config.serverType, { basePath });
|
|
59
88
|
this.server = this.app.createHttpServer();
|
|
60
89
|
}
|
|
61
90
|
setConfig(config) {
|
|
62
|
-
|
|
91
|
+
const { appConfig, runtimeEnvironment, globalData } = loadConfig(config);
|
|
92
|
+
this.config = appConfig;
|
|
93
|
+
this.runtimeEnvironment = runtimeEnvironment;
|
|
94
|
+
this.globalData = globalData;
|
|
63
95
|
}
|
|
64
96
|
getConfig() {
|
|
65
97
|
return this.config;
|
|
66
98
|
}
|
|
67
99
|
async init() {
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
100
|
+
if (this.initialized) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
// preemptively mark the server as initialized
|
|
104
|
+
this.initialized = true;
|
|
105
|
+
try {
|
|
106
|
+
// create the application server context
|
|
107
|
+
const context = await initContext(this.config, this.runtimeEnvironment, this.globalData);
|
|
108
|
+
// attach framework middleware to the server
|
|
109
|
+
initMiddleware(this.app, this.server, context);
|
|
110
|
+
}
|
|
111
|
+
catch (e) {
|
|
112
|
+
// reset the initialized property if the server fails to initialize
|
|
113
|
+
this.initialized = false;
|
|
114
|
+
throw e;
|
|
78
115
|
}
|
|
79
116
|
}
|
|
80
117
|
async listen(callback) {
|
|
@@ -136,7 +173,7 @@ export async function generateStaticSite(config) {
|
|
|
136
173
|
const { serverMode } = config;
|
|
137
174
|
if (serverMode === 'dev' || serverMode === 'compat') {
|
|
138
175
|
// TODO: dynamic imports are not generated in dev mode
|
|
139
|
-
// https://github.com/salesforce/lwr/issues/1111
|
|
176
|
+
// https://github.com/salesforce-experience-platform-emu/lwr/issues/1111
|
|
140
177
|
logger.warn('static generation in `dev` or `compat` mode is currently not fully supported');
|
|
141
178
|
}
|
|
142
179
|
const lwrApp = createServer(config);
|
|
@@ -146,7 +183,6 @@ export async function generateStaticSite(config) {
|
|
|
146
183
|
await new SiteGenerator().buildStaticApplication(lwrApp.getConfig(), dispatcher);
|
|
147
184
|
return lwrApp.getConfig();
|
|
148
185
|
}
|
|
149
|
-
export { buildServer } from './tools/server-build.js';
|
|
150
186
|
/**
|
|
151
187
|
* Create normalized config for static generation forcing the app config to come as src
|
|
152
188
|
*/
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { getAssetIdentity } from './utils/identity.js';
|
|
3
|
+
import { handleErrors } from './utils/error-handling.js';
|
|
4
|
+
function createAssetMiddleware(context) {
|
|
5
|
+
const { assetRegistry, runtimeEnvironment: { basePath }, } = context;
|
|
6
|
+
return async (req, res) => {
|
|
7
|
+
const { runtimeEnvironment } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
8
|
+
const { assetId, immutable, signature } = getAssetIdentity(req);
|
|
9
|
+
if (basePath && !assetId.specifier.startsWith(basePath)) {
|
|
10
|
+
assetId.specifier = path.join(basePath, assetId.specifier);
|
|
11
|
+
}
|
|
12
|
+
// Redirect if this is an external asset
|
|
13
|
+
const assetUri = await assetRegistry.resolveAssetUri(assetId, runtimeEnvironment);
|
|
14
|
+
if (assetUri.external) {
|
|
15
|
+
res.set({
|
|
16
|
+
Location: assetUri.uri,
|
|
17
|
+
'cache-control': 'public, max-age=60',
|
|
18
|
+
});
|
|
19
|
+
res.sendStatus(302);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const asset = await assetRegistry.getAsset({ ...assetId, signature }, runtimeEnvironment, req.isSiteGeneration());
|
|
23
|
+
if (req.isSiteGeneration()) {
|
|
24
|
+
res.setSiteGenerationMetadata({ asset });
|
|
25
|
+
}
|
|
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
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function assetMiddleware(app, context) {
|
|
39
|
+
const paths = context.appConfig.assets.map((a) => a.urlPath + app.getRegexWildcard());
|
|
40
|
+
app.get([...paths, '/:apiVersion/:assetType/:immutable?/s/:signature/' + app.getRegexWildcard()], handleErrors(createAssetMiddleware(context)));
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=asset-middleware.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { LATEST_SIGNATURE } from '@lwrjs/shared-utils';
|
|
2
|
+
import { descriptions } from '@lwrjs/diagnostics';
|
|
3
|
+
import { getRequestImporter } from './utils/request.js';
|
|
4
|
+
import { getModuleIdentity } from './utils/identity.js';
|
|
5
|
+
import { normalizeResolvedUris } from './utils/metadata.js';
|
|
6
|
+
import { createUnsignedBundleRedirect } from './redirects/unsigned-module-redirect.js';
|
|
7
|
+
import { handleErrors } from './utils/error-handling.js';
|
|
8
|
+
function createBundleMiddleware(context) {
|
|
9
|
+
const { moduleRegistry, moduleBundler } = context;
|
|
10
|
+
const unsignedBundleRedirect = createUnsignedBundleRedirect(moduleBundler);
|
|
11
|
+
return async (req, res) => {
|
|
12
|
+
if (!req.validateEnvironmentRequest(context.appConfig)) {
|
|
13
|
+
res.status(400);
|
|
14
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (!req.validateJsonRequest()) {
|
|
18
|
+
res.status(400);
|
|
19
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
23
|
+
const importer = req.query.importer ? await getRequestImporter(req, moduleRegistry) : undefined;
|
|
24
|
+
const { moduleId, signature } = getModuleIdentity(req, importer);
|
|
25
|
+
if (moduleId.importer || !signature) {
|
|
26
|
+
await unsignedBundleRedirect(req, res, moduleId, runtimeEnvironment, runtimeParams);
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const sourceMapUrl = req.path.replace('/bundle/', '/sourcemaps/bundle/');
|
|
30
|
+
const bundleDefinition = await moduleBundler.getModuleBundle(moduleId,
|
|
31
|
+
// bundle must be `true` to properly resolve bundles in amd
|
|
32
|
+
{ ...runtimeEnvironment, bundle: true, sourceMapUrl }, runtimeParams);
|
|
33
|
+
if (req.isSiteGeneration()) {
|
|
34
|
+
res.setSiteGenerationMetadata({
|
|
35
|
+
moduleDefinition: bundleDefinition,
|
|
36
|
+
resolvedUris: await normalizeResolvedUris(bundleDefinition, runtimeEnvironment, runtimeParams, moduleBundler, moduleRegistry),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (signature !== LATEST_SIGNATURE) {
|
|
40
|
+
res.setHeader('Cache-control', 'public, max-age=31536000, immutable');
|
|
41
|
+
}
|
|
42
|
+
res.status(200).type('application/javascript').send(bundleDefinition.code);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createSourceMapMiddleware(context) {
|
|
46
|
+
const { moduleBundler } = context;
|
|
47
|
+
return async (req, res) => {
|
|
48
|
+
if (!req.validateEnvironmentRequest(context.appConfig)) {
|
|
49
|
+
res.status(400);
|
|
50
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const { runtimeEnvironment } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
54
|
+
const { moduleId, signature } = getModuleIdentity(req);
|
|
55
|
+
const bundleDef = await moduleBundler.getModuleBundle(moduleId, runtimeEnvironment);
|
|
56
|
+
if (signature !== LATEST_SIGNATURE) {
|
|
57
|
+
res.setHeader('Cache-control', 'public, max-age=31536000, immutable');
|
|
58
|
+
}
|
|
59
|
+
res.status(200).type('application/json').send(bundleDef.map);
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
export function bundleMiddleware(app, context) {
|
|
63
|
+
app.get([
|
|
64
|
+
`/:apiVersion/bundle/:format/:compat?/l/:locale/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
65
|
+
`/:apiVersion/bundle/:format/:compat?/l/:locale/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
66
|
+
`/:apiVersion/bundle/:format/:compat?/l/:locale/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
67
|
+
`/:apiVersion/bundle/:format/:compat?/l/:locale/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
68
|
+
`/:apiVersion/bundle/:format/:compat?/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
69
|
+
`/:apiVersion/bundle/:format/:compat?/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
70
|
+
`/:apiVersion/bundle/:format/:compat?/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
71
|
+
`/:apiVersion/bundle/:format/:compat?/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
72
|
+
`/:apiVersion/bundle/:format/:compat?/l/:locale/e/:environment/bi/:bundleSpecifier/module/mi/:specifier`,
|
|
73
|
+
`/:apiVersion/bundle/:format/:compat?/l/:locale/bi/:bundleSpecifier/module/mi/:specifier`,
|
|
74
|
+
`/:apiVersion/bundle/:format/:compat?/e/:environment/bi/:bundleSpecifier/module/mi/:specifier`,
|
|
75
|
+
`/:apiVersion/bundle/:format/:compat?/bi/:bundleSpecifier/module/mi/:specifier`,
|
|
76
|
+
], handleErrors(createBundleMiddleware(context)));
|
|
77
|
+
app.get([
|
|
78
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/l/:locale/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
79
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/l/:locale/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
80
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/l/:locale/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
81
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/l/:locale/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
82
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
83
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/e/:environment/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
84
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/bi/:bundleSpecifier/module/mi/:specifier/latest/:prettyUrl?`,
|
|
85
|
+
`/:apiVersion/sourcemaps/bundle/:format/:compat?/bi/:bundleSpecifier/module/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
86
|
+
], handleErrors(createSourceMapMiddleware(context)));
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=bundle-middleware.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { WebSocketServer } from 'ws';
|
|
2
2
|
import { getCacheKeyFromJson } from '@lwrjs/shared-utils';
|
|
3
|
-
import { getRequestProperties } from './utils.js';
|
|
3
|
+
import { getRequestProperties } from './utils/request.js';
|
|
4
4
|
let hmr;
|
|
5
5
|
class Hmr {
|
|
6
6
|
constructor(server, context) {
|
|
@@ -52,8 +52,8 @@ class Hmr {
|
|
|
52
52
|
version,
|
|
53
53
|
};
|
|
54
54
|
const modulesCacheId = getCacheKeyFromJson({ format, compat, debug });
|
|
55
|
-
const newUri = moduleRegistry.
|
|
56
|
-
const oldUri = moduleRegistry.
|
|
55
|
+
const newUri = moduleRegistry.resolveModuleUriSync(moduleId, signature, runtimeEnvironment, runtimeParams);
|
|
56
|
+
const oldUri = moduleRegistry.resolveModuleUriSync(moduleId, 'latest', runtimeEnvironment, runtimeParams);
|
|
57
57
|
if (this.connectedClients) {
|
|
58
58
|
for (const [ws, cacheId] of this.connectedClients) {
|
|
59
59
|
if (cacheId === modulesCacheId) {
|
|
@@ -100,7 +100,7 @@ class Hmr {
|
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
export
|
|
103
|
+
export function hmrMiddleware(server, context) {
|
|
104
104
|
hmr = new Hmr(server, context);
|
|
105
105
|
hmr.setupHotModuleReload();
|
|
106
106
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
export
|
|
1
|
+
export function localeMiddleware(app, context) {
|
|
2
2
|
const { defaultLocale } = context.runtimeEnvironment;
|
|
3
3
|
app.use(async (req, res, next) => {
|
|
4
4
|
const langs = req.acceptsLanguages();
|
|
5
5
|
req.locale = langs?.length > 0 ? langs[0] : defaultLocale;
|
|
6
|
+
// await is required when calling next to support koa
|
|
6
7
|
await next();
|
|
7
8
|
});
|
|
8
9
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { getImportMetadataMappings } from '@lwrjs/shared-utils';
|
|
2
|
+
import { descriptions } from '@lwrjs/diagnostics';
|
|
3
|
+
import { getMappingIdentity } from './utils/identity.js';
|
|
4
|
+
import { handleErrors } from './utils/error-handling.js';
|
|
5
|
+
function createMappingMiddleware(context) {
|
|
6
|
+
const { moduleBundler, moduleRegistry } = context;
|
|
7
|
+
return async (req, res) => {
|
|
8
|
+
if (!req.validateEnvironmentRequest(context.appConfig)) {
|
|
9
|
+
res.status(400);
|
|
10
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
14
|
+
const { moduleIds } = getMappingIdentity(req);
|
|
15
|
+
const importMetadata = await getImportMetadataMappings(moduleIds, runtimeEnvironment, runtimeParams, moduleRegistry, moduleBundler);
|
|
16
|
+
if (req.isSiteGeneration()) {
|
|
17
|
+
res.setSiteGenerationMetadata({ importMetadata });
|
|
18
|
+
}
|
|
19
|
+
res.status(200).type('application/json').send(importMetadata);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export function mappingMiddleware(app, context) {
|
|
23
|
+
app.get([
|
|
24
|
+
`/:apiVersion/mapping/:format/:compat/l/:locale/e/:environment/bi/:bundleSpecifier/mp/:specifiers`,
|
|
25
|
+
`/:apiVersion/mapping/:format/:compat/l/:locale/e/:environment/mp/:specifiers`,
|
|
26
|
+
`/:apiVersion/mapping/:format/:compat/l/:locale/bi/:bundleSpecifier/mp/:specifiers`,
|
|
27
|
+
`/:apiVersion/mapping/:format/:compat/e/:environment/bi/:bundleSpecifier/mp/:specifiers`,
|
|
28
|
+
`/:apiVersion/mapping/:format/:compat/l/:locale/mp/:specifiers`,
|
|
29
|
+
`/:apiVersion/mapping/:format/:compat/e/:environment/mp/:specifiers`,
|
|
30
|
+
`/:apiVersion/mapping/:format/:compat/bi/:bundleSpecifier/mp/:specifiers`,
|
|
31
|
+
`/:apiVersion/mapping/:format/:compat/mp/:specifiers`,
|
|
32
|
+
], handleErrors(createMappingMiddleware(context)));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=mapping-middleware.js.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { descriptions } from '@lwrjs/diagnostics';
|
|
2
|
+
import { LATEST_SIGNATURE, serializeModuleToJson } from '@lwrjs/shared-utils';
|
|
3
|
+
import { getRequestImporter } from './utils/request.js';
|
|
4
|
+
import { getModuleIdentity } from './utils/identity.js';
|
|
5
|
+
import { createUnsignedModuleRedirect } from './redirects/unsigned-module-redirect.js';
|
|
6
|
+
import { handleErrors } from './utils/error-handling.js';
|
|
7
|
+
function createModuleMiddleware(context) {
|
|
8
|
+
const { moduleRegistry } = context;
|
|
9
|
+
const unsignedRedirect = createUnsignedModuleRedirect(moduleRegistry);
|
|
10
|
+
return async (req, res) => {
|
|
11
|
+
if (!req.validateEnvironmentRequest(context.appConfig)) {
|
|
12
|
+
res.status(400);
|
|
13
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (!req.validateJsonRequest()) {
|
|
17
|
+
res.status(400);
|
|
18
|
+
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
22
|
+
const importer = req.query.importer ? await getRequestImporter(req, moduleRegistry) : undefined;
|
|
23
|
+
const { moduleId, signature } = getModuleIdentity(req, importer);
|
|
24
|
+
if (moduleId.importer || !signature) {
|
|
25
|
+
await unsignedRedirect(req, res, moduleId, runtimeEnvironment, runtimeParams);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const moduleDefinition = await moduleRegistry.getLinkedModule(moduleId,
|
|
29
|
+
// bundle must be `false` to resolve amd modules in `prod-compat` mode
|
|
30
|
+
{ ...runtimeEnvironment, bundle: false }, runtimeParams);
|
|
31
|
+
const { ownHash, linkedSource } = moduleDefinition;
|
|
32
|
+
// validate the requested instances exists
|
|
33
|
+
if (signature !== LATEST_SIGNATURE && ownHash !== signature) {
|
|
34
|
+
res.status(404).send(descriptions.UNRESOLVABLE.SIGNED_MODULE(moduleId.specifier, signature).message);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
if (req.isSiteGeneration()) {
|
|
38
|
+
res.setSiteGenerationMetadata({ moduleDefinition });
|
|
39
|
+
}
|
|
40
|
+
if (req.isJsonRequest()) {
|
|
41
|
+
const json = await serializeModuleToJson(linkedSource, moduleDefinition, moduleRegistry, runtimeParams);
|
|
42
|
+
res.status(200).type('application/json').send(json);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
res.status(200).type('application/javascript').send(linkedSource);
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
export function moduleMiddleware(app, context) {
|
|
49
|
+
app.get([
|
|
50
|
+
`/:apiVersion/module/:format/:compat/l/:locale/e/:environment/mi/:specifier/latest/:prettyUrl?`,
|
|
51
|
+
`/:apiVersion/module/:format/:compat/l/:locale/e/:environment/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
52
|
+
`/:apiVersion/module/:format/:compat/l/:locale/mi/:specifier/latest/:prettyUrl?`,
|
|
53
|
+
`/:apiVersion/module/:format/:compat/l/:locale/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
54
|
+
`/:apiVersion/module/:format/:compat/e/:environment/mi/:specifier/latest/:prettyUrl?`,
|
|
55
|
+
`/:apiVersion/module/:format/:compat/e/:environment/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
56
|
+
`/:apiVersion/module/:format/:compat/mi/:specifier/latest/:prettyUrl?`,
|
|
57
|
+
`/:apiVersion/module/:format/:compat/mi/:specifier/s/:signature/:prettyUrl?`,
|
|
58
|
+
`/:apiVersion/module/:format/:compat/l/:locale/e/:environment/mi/:specifier`,
|
|
59
|
+
`/:apiVersion/module/:format/:compat/l/:locale/mi/:specifier`,
|
|
60
|
+
`/:apiVersion/module/:format/:compat/e/:environment/mi/:specifier`,
|
|
61
|
+
`/:apiVersion/module/:format/:compat/mi/:specifier`,
|
|
62
|
+
], handleErrors(createModuleMiddleware(context)));
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=module-middleware.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AbstractModuleId, MiddlewareRequest, MiddlewareResponse, ModuleBundler, ModuleRegistry, RuntimeEnvironment, RuntimeParams } from '@lwrjs/types';
|
|
2
|
+
declare type UnsignedRedirect = (req: MiddlewareRequest, res: MiddlewareResponse, moduleId: AbstractModuleId, runtimeEnvironment: RuntimeEnvironment, runtimeParams: RuntimeParams) => Promise<void>;
|
|
3
|
+
export declare function createUnsignedModuleRedirect(moduleRegistry: ModuleRegistry): UnsignedRedirect;
|
|
4
|
+
export declare function createUnsignedBundleRedirect(moduleBundler: ModuleBundler): UnsignedRedirect;
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=unsigned-module-redirect.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const HEADER_LOCATION = 'Location';
|
|
2
|
+
const STATUS_FOUND = 302;
|
|
3
|
+
export function createUnsignedModuleRedirect(moduleRegistry) {
|
|
4
|
+
return async (req, res, moduleId, runtimeEnvironment, runtimeParams) => {
|
|
5
|
+
const jsonQuery = getJsonQualifier(req, runtimeEnvironment);
|
|
6
|
+
const { moduleEntry, ownHash } = await moduleRegistry.getModule(moduleId);
|
|
7
|
+
const uri = await moduleRegistry.resolveModuleUri({ ...moduleId, version: moduleEntry.version }, runtimeEnvironment, runtimeParams, ownHash);
|
|
8
|
+
sendRedirect(res, `${uri}${jsonQuery}`);
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function createUnsignedBundleRedirect(moduleBundler) {
|
|
12
|
+
return async (req, res, moduleId, runtimeEnvironment, runtimeParams) => {
|
|
13
|
+
const jsonQuery = getJsonQualifier(req, runtimeEnvironment);
|
|
14
|
+
const uri = await moduleBundler.resolveModuleUri(moduleId, runtimeEnvironment, runtimeParams);
|
|
15
|
+
sendRedirect(res, `${uri}${jsonQuery}`);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
function getJsonQualifier(req, runtimeEnvironment) {
|
|
19
|
+
return req.isJsonRequest() ? `${runtimeEnvironment.debug ? '&' : '?'}json` : '';
|
|
20
|
+
}
|
|
21
|
+
function sendRedirect(res, url) {
|
|
22
|
+
res.setHeader(HEADER_LOCATION, url);
|
|
23
|
+
res.sendStatus(STATUS_FOUND);
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=unsigned-module-redirect.js.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { descriptions } from '@lwrjs/diagnostics';
|
|
2
|
+
import { getResourceIdentity } from './utils/identity.js';
|
|
3
|
+
import { handleErrors } from './utils/error-handling.js';
|
|
4
|
+
function createResourceMiddleware(context) {
|
|
5
|
+
const { resourceRegistry } = context;
|
|
6
|
+
return async (req, res) => {
|
|
7
|
+
if (!req.validateEnvironmentRequest(context.appConfig)) {
|
|
8
|
+
res.status(400).send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
12
|
+
const { resourceId } = getResourceIdentity(req);
|
|
13
|
+
const resource = await resourceRegistry.getResource(resourceId, runtimeEnvironment, runtimeParams);
|
|
14
|
+
if (req.isSiteGeneration()) {
|
|
15
|
+
res.setSiteGenerationMetadata({ resource });
|
|
16
|
+
}
|
|
17
|
+
if (resource && resource.content) {
|
|
18
|
+
const type = resource.type === 'text/css' ? resource.type : 'application/javascript';
|
|
19
|
+
res.status(200).type(type).send(resource.content);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (resource && resource.stream) {
|
|
23
|
+
res.status(200).type(resource.type).stream(resource.stream());
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
res.status(404).send(descriptions.UNRESOLVABLE.RESOURCE(resourceId.specifier).message);
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function resourceMiddleware(app, context) {
|
|
30
|
+
app.get([
|
|
31
|
+
`/:apiVersion/resource/:format/l/:locale/e/:environment/:specifier/:prettyUrl?`,
|
|
32
|
+
`/:apiVersion/resource/:format/l/:locale/:specifier/:prettyUrl?`,
|
|
33
|
+
`/:apiVersion/resource/:format/e/:environment/:specifier/:prettyUrl?`,
|
|
34
|
+
`/:apiVersion/resource/:format/:specifier/:prettyUrl?`,
|
|
35
|
+
], handleErrors(createResourceMiddleware(context)));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=resource-middleware.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { descriptions, DiagnosticsError, LwrUnresolvableError } from '@lwrjs/diagnostics';
|
|
2
|
+
function createReturnStatus(error, url) {
|
|
3
|
+
if (error instanceof LwrUnresolvableError &&
|
|
4
|
+
error.diagnostics[0].description.category === 'lwrUnresolvable/invalid') {
|
|
5
|
+
return { status: 400, message: error.message };
|
|
6
|
+
}
|
|
7
|
+
if (error instanceof LwrUnresolvableError) {
|
|
8
|
+
return { status: 404, message: error.message };
|
|
9
|
+
}
|
|
10
|
+
return { status: 500, message: descriptions.UNRESOLVABLE.SERVER_ERROR(url).message };
|
|
11
|
+
}
|
|
12
|
+
export function handleErrors(middleware) {
|
|
13
|
+
return async (req, res, next) => {
|
|
14
|
+
try {
|
|
15
|
+
await middleware(req, res, next);
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
if (err instanceof DiagnosticsError) {
|
|
19
|
+
console.error('LWR Diagnostic Error: ' + err.message);
|
|
20
|
+
console.error(err.diagnostics);
|
|
21
|
+
console.error(err.stack);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.error(err);
|
|
25
|
+
}
|
|
26
|
+
const { status, message } = createReturnStatus(err, req.originalUrl);
|
|
27
|
+
res.status(status);
|
|
28
|
+
res.send(message);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=error-handling.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AssetIdentity, MappingIdentity, MiddlewareRequest, ModuleIdentity, ResourceIdentity } from '@lwrjs/types';
|
|
2
|
+
export declare function getModuleIdentity(req: MiddlewareRequest, importer?: string): ModuleIdentity;
|
|
3
|
+
export declare function getMappingIdentity(req: MiddlewareRequest): MappingIdentity;
|
|
4
|
+
export declare function getResourceIdentity(req: MiddlewareRequest): ResourceIdentity;
|
|
5
|
+
export declare function getAssetIdentity(req: MiddlewareRequest): AssetIdentity;
|
|
6
|
+
//# sourceMappingURL=identity.d.ts.map
|