@lwrjs/core 0.11.0-alpha.1 → 0.11.0-alpha.11
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 +2 -0
- package/build/cjs/context/server.cjs +1 -1
- package/build/cjs/index.cjs +3 -2
- package/build/cjs/middleware/asset-middleware.cjs +2 -1
- package/build/cjs/middleware/bundle-middleware.cjs +17 -6
- package/build/cjs/middleware/hmr-middleware.cjs +6 -5
- package/build/cjs/middleware/locale-middleware.cjs +2 -2
- package/build/cjs/middleware/mapping-middleware.cjs +9 -3
- package/build/cjs/middleware/module-middleware.cjs +8 -3
- package/build/cjs/middleware/request-processor-middleware.cjs +64 -0
- package/build/cjs/middleware/resource-middleware.cjs +8 -3
- package/build/cjs/middleware/utils/error-handling.cjs +5 -4
- package/build/cjs/middleware/view-middleware.cjs +16 -14
- package/build/cjs/middleware.cjs +2 -0
- package/build/cjs/tools/server-warmup.cjs +7 -7
- package/build/cjs/tools/static-generation.cjs +68 -67
- package/build/cjs/tools/utils/network-dispatcher.cjs +12 -11
- package/build/es/context/provider.js +2 -1
- package/build/es/context/server.js +1 -2
- package/build/es/index.js +5 -4
- package/build/es/middleware/asset-middleware.js +2 -2
- package/build/es/middleware/bundle-middleware.js +6 -6
- package/build/es/middleware/hmr-middleware.js +6 -5
- package/build/es/middleware/locale-middleware.js +2 -2
- package/build/es/middleware/mapping-middleware.js +3 -3
- package/build/es/middleware/module-middleware.js +3 -3
- package/build/es/middleware/request-processor-middleware.d.ts +3 -0
- package/build/es/middleware/request-processor-middleware.js +53 -0
- package/build/es/middleware/resource-middleware.js +3 -3
- package/build/es/middleware/utils/error-handling.js +5 -4
- package/build/es/middleware/view-middleware.js +17 -14
- package/build/es/middleware.d.ts +1 -0
- package/build/es/middleware.js +1 -0
- package/build/es/tools/server-warmup.js +3 -3
- package/build/es/tools/static-generation.d.ts +6 -2
- package/build/es/tools/static-generation.js +62 -54
- package/build/es/tools/types.d.ts +2 -1
- package/build/es/tools/utils/network-dispatcher.js +2 -1
- package/package.json +31 -29
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse passed to us via the X-Mobify-Request-Class.
|
|
3
|
+
*
|
|
4
|
+
* basePath: The dynamic base path
|
|
5
|
+
* '' or undefined -> LWR basePath ''
|
|
6
|
+
* token or /token -> LWR basePath '/token'
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
import { logger } from '@lwrjs/diagnostics';
|
|
10
|
+
const MRT_REQUEST_CLASS = 'X-Mobify-Request-Class';
|
|
11
|
+
const MRT_REQUEST_CLASS_KEY = MRT_REQUEST_CLASS.toLowerCase();
|
|
12
|
+
export function requestProcessorMiddleware(app, context) {
|
|
13
|
+
const { basePath } = context.runtimeEnvironment;
|
|
14
|
+
app.use(async (req, _res, next) => {
|
|
15
|
+
let requestClass;
|
|
16
|
+
if (req.headers) {
|
|
17
|
+
// If debug print log all the headers
|
|
18
|
+
if (logger.currentLevel === 'debug' || logger.currentLevel == 'verbose') {
|
|
19
|
+
// Loop through and print each header
|
|
20
|
+
for (const headerName in req.headers) {
|
|
21
|
+
logger.debug(`[request-processor-middleware] Header ${headerName}: ${req.headers[headerName]}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
requestClass = req.headers[MRT_REQUEST_CLASS_KEY];
|
|
25
|
+
}
|
|
26
|
+
if (req.headers && typeof requestClass === 'string') {
|
|
27
|
+
const parsedRequestClass = parseRequestClass(requestClass);
|
|
28
|
+
logger.debug(`[request-processor-middleware] parsedRequestClass?.basePath: ${parsedRequestClass?.basePath}`);
|
|
29
|
+
const pathValue = parsedRequestClass?.basePath || basePath || '';
|
|
30
|
+
// If base path is '' or starts with / leave it alone
|
|
31
|
+
req.basePath = pathValue === '' || pathValue.indexOf('/') === 0 ? pathValue : `/${pathValue}`;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
logger.debug(`[request-processor-middleware] ${MRT_REQUEST_CLASS_KEY} ignored ${req.headers ? req.headers[MRT_REQUEST_CLASS_KEY] : 'no-headers'}`);
|
|
35
|
+
req.basePath = basePath;
|
|
36
|
+
}
|
|
37
|
+
// await is required when calling next to support koa
|
|
38
|
+
await next();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
function parseRequestClass(requestClass) {
|
|
42
|
+
// Split the Forwarded header into individual key-value pairs
|
|
43
|
+
const keyValuePairs = requestClass.split(';');
|
|
44
|
+
// Create an object to store the parsed values
|
|
45
|
+
const parsed = {};
|
|
46
|
+
// Iterate through the key-value pairs and populate the parsed object
|
|
47
|
+
for (const pair of keyValuePairs) {
|
|
48
|
+
const [key, value] = pair.split('=');
|
|
49
|
+
parsed[key] = value;
|
|
50
|
+
}
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=request-processor-middleware.js.map
|
|
@@ -2,13 +2,13 @@ import { descriptions } from '@lwrjs/diagnostics';
|
|
|
2
2
|
import { getResourceIdentity } from './utils/identity.js';
|
|
3
3
|
import { handleErrors } from './utils/error-handling.js';
|
|
4
4
|
function createResourceMiddleware(context) {
|
|
5
|
-
const { resourceRegistry } = context;
|
|
5
|
+
const { appConfig, appConfig: { i18n }, resourceRegistry, runtimeEnvironment: defaultRuntimeEnvironment, } = context;
|
|
6
6
|
return async (req, res) => {
|
|
7
|
-
if (!req.validateEnvironmentRequest(
|
|
7
|
+
if (!req.validateEnvironmentRequest(appConfig)) {
|
|
8
8
|
res.status(400).send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
9
9
|
return;
|
|
10
10
|
}
|
|
11
|
-
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(
|
|
11
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(defaultRuntimeEnvironment, i18n);
|
|
12
12
|
const { resourceId } = getResourceIdentity(req);
|
|
13
13
|
const resource = await resourceRegistry.getResource(resourceId, runtimeEnvironment, runtimeParams);
|
|
14
14
|
if (req.isSiteGeneration()) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { descriptions, DiagnosticsError, LwrUnresolvableError } from '@lwrjs/diagnostics';
|
|
2
|
+
import { logger } from '@lwrjs/diagnostics';
|
|
2
3
|
function createReturnStatus(error, url) {
|
|
3
4
|
if (error instanceof LwrUnresolvableError &&
|
|
4
5
|
error.diagnostics[0].description.category === 'lwrUnresolvable/invalid') {
|
|
@@ -16,12 +17,12 @@ export function handleErrors(middleware) {
|
|
|
16
17
|
}
|
|
17
18
|
catch (err) {
|
|
18
19
|
if (err instanceof DiagnosticsError) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
logger.error('LWR Diagnostic Error: ' + err.message);
|
|
21
|
+
logger.error(err.diagnostics);
|
|
22
|
+
logger.error(err.stack);
|
|
22
23
|
}
|
|
23
24
|
else {
|
|
24
|
-
|
|
25
|
+
logger.error(err);
|
|
25
26
|
}
|
|
26
27
|
const { status, message } = createReturnStatus(err, req.originalUrl);
|
|
27
28
|
res.status(status);
|
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import { descriptions } from '@lwrjs/diagnostics';
|
|
1
|
+
import { descriptions, logger } from '@lwrjs/diagnostics';
|
|
2
2
|
import { getClientRoutes } from '@lwrjs/router';
|
|
3
|
-
import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes,
|
|
3
|
+
import { decodeViewPath, extractRequestParams, getClientBootstrapConfigurationRoutes, shortestTtl, } from '@lwrjs/shared-utils';
|
|
4
4
|
import { handleErrors } from './utils/error-handling.js';
|
|
5
5
|
import { LwrViewHandler } from '@lwrjs/view-registry';
|
|
6
|
-
const CANONICAL_VIEW_ROUTES = [
|
|
7
|
-
`/:apiVersion/application/:format/l/:locale/ai/:appId`,
|
|
8
|
-
`/:apiVersion/application/:format/l/:locale/e/:environment/ai/:appId`,
|
|
9
|
-
`/:apiVersion/application/:format/ai/:appId`,
|
|
10
|
-
`/:apiVersion/application/:format/e/:environment/ai/:appId`,
|
|
11
|
-
];
|
|
12
6
|
function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
13
7
|
const errorRoute = errorRoutes.find((route) => route.status === 500);
|
|
8
|
+
const appConfig = context.appConfig;
|
|
9
|
+
const { environment: environmentConfig, i18n } = appConfig;
|
|
14
10
|
return async (req, res) => {
|
|
15
|
-
if (!req.validateEnvironmentRequest(
|
|
11
|
+
if (!req.validateEnvironmentRequest(appConfig)) {
|
|
16
12
|
res.status(400);
|
|
17
13
|
res.send(descriptions.UNRESOLVABLE.INVALID_ENVIRONMENT(req.params.environment).message);
|
|
18
14
|
return;
|
|
@@ -22,9 +18,8 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
22
18
|
res.send(descriptions.UNRESOLVABLE.INVALID_JSON().message);
|
|
23
19
|
return;
|
|
24
20
|
}
|
|
25
|
-
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
21
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment, i18n);
|
|
26
22
|
// set the default environment if an environment is configured in the app config
|
|
27
|
-
const { environment: environmentConfig } = context.appConfig;
|
|
28
23
|
if (!runtimeParams.environment && environmentConfig?.default) {
|
|
29
24
|
runtimeParams.environment = environmentConfig.default;
|
|
30
25
|
}
|
|
@@ -72,7 +67,7 @@ function createViewMiddleware(route, errorRoutes, context, viewHandler) {
|
|
|
72
67
|
}
|
|
73
68
|
function createConfigMiddleware(routes, context, viewHandler) {
|
|
74
69
|
return async (req, res) => {
|
|
75
|
-
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment);
|
|
70
|
+
const { runtimeEnvironment, runtimeParams } = req.getRuntimeContext(context.runtimeEnvironment, context.appConfig.i18n);
|
|
76
71
|
const { appId, encodedViewPath } = req.params;
|
|
77
72
|
// match the app id to a route
|
|
78
73
|
const route = routes.find((route) => route.id === appId);
|
|
@@ -119,7 +114,7 @@ function createNotFoundMiddleware(errorRoutes, context, viewHandler) {
|
|
|
119
114
|
}
|
|
120
115
|
export function viewMiddleware(app, context) {
|
|
121
116
|
const { appConfig, viewRegistry, moduleRegistry, routeHandlers } = context;
|
|
122
|
-
const { routes, errorRoutes } = appConfig;
|
|
117
|
+
const { i18n, routes, errorRoutes } = appConfig;
|
|
123
118
|
const viewHandler = new LwrViewHandler({ viewRegistry, moduleRegistry, routeHandlers }, appConfig);
|
|
124
119
|
// create and attach middleware for each route
|
|
125
120
|
for (const route of routes) {
|
|
@@ -129,7 +124,15 @@ export function viewMiddleware(app, context) {
|
|
|
129
124
|
const prefix = route.path === '/' ? '' : route.path;
|
|
130
125
|
subRoutes.routes.forEach((subRoute) => subRoute.uri !== route.path && paths.push(`${prefix}${subRoute.uri}`));
|
|
131
126
|
}
|
|
132
|
-
|
|
127
|
+
// Add localized routes
|
|
128
|
+
if (i18n.uriPattern === 'path-prefix') {
|
|
129
|
+
const supportedStr = i18n.locales.map((l) => l.id).join('|');
|
|
130
|
+
paths.forEach((routePath) => {
|
|
131
|
+
const localizedPath = `/:locale(${supportedStr})${routePath}`;
|
|
132
|
+
logger.debug(`[view-middleware] Add localized path ${localizedPath}`);
|
|
133
|
+
paths.push(localizedPath);
|
|
134
|
+
});
|
|
135
|
+
}
|
|
133
136
|
app.get(paths, handleErrors(createViewMiddleware(route, errorRoutes, context, viewHandler)));
|
|
134
137
|
}
|
|
135
138
|
// create and attach middleware for bootstrap configurations
|
package/build/es/middleware.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { requestProcessorMiddleware } from './middleware/request-processor-middleware.js';
|
|
1
2
|
export { localeMiddleware } from './middleware/locale-middleware.js';
|
|
2
3
|
export { hmrMiddleware } from './middleware/hmr-middleware.js';
|
|
3
4
|
export { moduleMiddleware } from './middleware/module-middleware.js';
|
package/build/es/middleware.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// handler bundle size. For example, importing `@lwrjs/core` will pull in ALL `@lwrjs/server` dependencies
|
|
3
3
|
// which includes both `koa` and `express`. Importing `@lwrjs/core/middleware` will only pull in the
|
|
4
4
|
// middleware dependencies.
|
|
5
|
+
export { requestProcessorMiddleware } from './middleware/request-processor-middleware.js';
|
|
5
6
|
export { localeMiddleware } from './middleware/locale-middleware.js';
|
|
6
7
|
export { hmrMiddleware } from './middleware/hmr-middleware.js';
|
|
7
8
|
export { moduleMiddleware } from './middleware/module-middleware.js';
|
|
@@ -2,19 +2,19 @@ import SiteGenerator from './static-generation.js';
|
|
|
2
2
|
import { skipDirCreation } from './utils/dir.js';
|
|
3
3
|
import NetworkDispatcher from './utils/network-dispatcher.js';
|
|
4
4
|
import { getRuntimeEnvironment } from '@lwrjs/config';
|
|
5
|
-
import { logger, WARN, INFO } from '@lwrjs/
|
|
5
|
+
import { logger, WARN, INFO } from '@lwrjs/diagnostics';
|
|
6
6
|
export async function warmupServer(config, internalRequestKey) {
|
|
7
7
|
// De-duplicate warming messages if log level is warn or info
|
|
8
8
|
if (!logger.currentLevel || logger.currentLevel == WARN || logger.currentLevel == INFO) {
|
|
9
9
|
logger.setOptions({ dedupe: new Set([WARN]) });
|
|
10
10
|
}
|
|
11
11
|
logger.info('[Server Warmup] starting');
|
|
12
|
-
const {
|
|
12
|
+
const { basePath, i18n, port, routes, staticSiteGenerator } = config;
|
|
13
13
|
staticSiteGenerator.outputDir = skipDirCreation;
|
|
14
14
|
const urlRewriteMap = new Map();
|
|
15
15
|
const runtimeEnvironment = getRuntimeEnvironment(config);
|
|
16
16
|
// For each locale, generate all the modules
|
|
17
|
-
await new SiteGenerator().generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, new NetworkDispatcher(port, internalRequestKey), staticSiteGenerator.outputDir, urlRewriteMap);
|
|
17
|
+
await new SiteGenerator().generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, new NetworkDispatcher(port, internalRequestKey), staticSiteGenerator.outputDir, i18n, urlRewriteMap);
|
|
18
18
|
logger.info('[Server Warmup] complete');
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=server-warmup.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ImportMetadata, LwrDispatcher, StaticSiteGenerator, LwrRoute, NormalizedLwrGlobalConfig, RuntimeEnvironment } from '@lwrjs/types';
|
|
1
|
+
import type { ImportMetadata, LwrDispatcher, StaticSiteGenerator, LwrRoute, NormalizedLwrGlobalConfig, RuntimeEnvironment, I18NConfig } from '@lwrjs/types';
|
|
2
2
|
import type { ResourceContextOpts, SiteConfig, ViewImportMetadata } from './types.js';
|
|
3
3
|
export default class SiteGenerator {
|
|
4
4
|
/**
|
|
@@ -14,7 +14,11 @@ export default class SiteGenerator {
|
|
|
14
14
|
/**
|
|
15
15
|
* Crawl all view routes for a site
|
|
16
16
|
*/
|
|
17
|
-
generateRoutes(runtimeEnvironment: RuntimeEnvironment, staticSiteGenerator: StaticSiteGenerator, routes: LwrRoute[], basePath: string, dispatcher: LwrDispatcher, outputDir: string, urlRewriteMap?: Map<string, string>): Promise<void>;
|
|
17
|
+
generateRoutes(runtimeEnvironment: RuntimeEnvironment, staticSiteGenerator: StaticSiteGenerator, routes: LwrRoute[], basePath: string, dispatcher: LwrDispatcher, outputDir: string, i18n: I18NConfig, urlRewriteMap?: Map<string, string>): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Generate all routes for a given locale
|
|
20
|
+
*/
|
|
21
|
+
private generateRoutesForLocale;
|
|
18
22
|
/**
|
|
19
23
|
* Creates a function to dispatch the root requests for a given view url
|
|
20
24
|
*/
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { performance } from 'perf_hooks';
|
|
2
|
-
import {
|
|
2
|
+
import { logger, WARN, INFO } from '@lwrjs/diagnostics';
|
|
3
|
+
import { getSpecifier, getFeatureFlags, hashContent, isSelfUrl, getModuleUriPrefix, getMappingUriPrefix, isExternalUrl, mimeLookup, getViewUri, } from '@lwrjs/shared-utils';
|
|
3
4
|
import { SiteMetadataImpl } from '@lwrjs/static/site-metadata';
|
|
4
5
|
import { join, dirname, extname, normalize } from 'path';
|
|
5
6
|
import fs from 'fs-extra';
|
|
6
7
|
import { writeResponse } from './utils/stream.js';
|
|
7
|
-
import {
|
|
8
|
+
import { createResourceDir } from './utils/dir.js';
|
|
8
9
|
import { getRuntimeEnvironment } from '@lwrjs/config';
|
|
9
10
|
export default class SiteGenerator {
|
|
10
11
|
/**
|
|
@@ -23,7 +24,7 @@ export default class SiteGenerator {
|
|
|
23
24
|
if (!logger.currentLevel || logger.currentLevel == WARN || logger.currentLevel == INFO) {
|
|
24
25
|
logger.setOptions({ dedupe: new Set([WARN]) });
|
|
25
26
|
}
|
|
26
|
-
const {
|
|
27
|
+
const { assets, basePath, i18n, rootDir, routes, staticSiteGenerator } = config;
|
|
27
28
|
if (!staticSiteGenerator.outputDir) {
|
|
28
29
|
staticSiteGenerator.outputDir = 'site';
|
|
29
30
|
}
|
|
@@ -36,11 +37,10 @@ export default class SiteGenerator {
|
|
|
36
37
|
logger.info(`[SSG] Reusing existing output directory: ${outputDir}`);
|
|
37
38
|
}
|
|
38
39
|
const urlRewriteMap = new Map();
|
|
39
|
-
const { basePath } = config;
|
|
40
40
|
const runtimeEnvironment = getRuntimeEnvironment(config);
|
|
41
41
|
// For each locale, generate all the modules
|
|
42
42
|
logger.info(`[SSG] Building routes (this may take some time to complete)`);
|
|
43
|
-
await this.generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, dispatcher, outputDir, urlRewriteMap);
|
|
43
|
+
await this.generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, dispatcher, outputDir, i18n, urlRewriteMap);
|
|
44
44
|
// Write redirect files
|
|
45
45
|
this.writeNetlifyRedirectConfig(outputDir, urlRewriteMap);
|
|
46
46
|
// Copy over assets
|
|
@@ -52,44 +52,57 @@ export default class SiteGenerator {
|
|
|
52
52
|
/**
|
|
53
53
|
* Crawl all view routes for a site
|
|
54
54
|
*/
|
|
55
|
-
async generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, dispatcher, outputDir, urlRewriteMap = new Map()) {
|
|
56
|
-
if (!staticSiteGenerator.locales) {
|
|
57
|
-
staticSiteGenerator.locales = ['en-US'];
|
|
58
|
-
}
|
|
55
|
+
async generateRoutes(runtimeEnvironment, staticSiteGenerator, routes, basePath, dispatcher, outputDir, i18n, urlRewriteMap = new Map()) {
|
|
59
56
|
const generateUrl = this.createGenerateURLFunction(dispatcher);
|
|
60
57
|
// Note: generateUrl can consume a lot of memory so we need to do this sequentially
|
|
61
58
|
const { skipBaseDocumentGeneration = false } = staticSiteGenerator;
|
|
62
|
-
|
|
59
|
+
// If there is not a know URL pattern it is expected the app is accounting with the locale in the routes
|
|
60
|
+
if (!i18n.uriPattern) {
|
|
61
|
+
// eslint-disable-next-line no-await-in-loop
|
|
62
|
+
await this.generateRoutesForLocale(routes, outputDir, { id: i18n.defaultLocale }, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n, basePath, generateUrl, staticSiteGenerator, dispatcher);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
63
65
|
// Generate all the routes
|
|
64
|
-
for (const
|
|
65
|
-
|
|
66
|
+
for (const locale of i18n.locales) {
|
|
67
|
+
logger.debug(`[SSG] Generate routes of locale: ${locale.id}`);
|
|
66
68
|
// eslint-disable-next-line no-await-in-loop
|
|
67
|
-
await
|
|
68
|
-
}
|
|
69
|
-
// Generate any additional urls
|
|
70
|
-
if (staticSiteGenerator._additionalRoutePaths) {
|
|
71
|
-
for (const uri of staticSiteGenerator._additionalRoutePaths) {
|
|
72
|
-
const siteConfig = this.createSiteConfig(outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment);
|
|
73
|
-
// eslint-disable-next-line no-await-in-loop
|
|
74
|
-
await generateUrl(uri, siteConfig);
|
|
75
|
-
}
|
|
69
|
+
await this.generateRoutesForLocale(routes, outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n, basePath, generateUrl, staticSiteGenerator, dispatcher);
|
|
76
70
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Generate all routes for a given locale
|
|
75
|
+
*/
|
|
76
|
+
async generateRoutesForLocale(routes, outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n, basePath, generateUrl, staticSiteGenerator, dispatcher) {
|
|
77
|
+
for (const route of routes) {
|
|
78
|
+
const siteConfig = this.createSiteConfig(outputDir, locale.id, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n);
|
|
79
|
+
const localizedPath = getViewUri(route.path, basePath, locale.id, i18n);
|
|
80
|
+
// eslint-disable-next-line no-await-in-loop
|
|
81
|
+
await generateUrl(localizedPath, siteConfig);
|
|
82
|
+
}
|
|
83
|
+
// Generate any additional urls
|
|
84
|
+
if (staticSiteGenerator._additionalRoutePaths) {
|
|
85
|
+
for (const uri of staticSiteGenerator._additionalRoutePaths) {
|
|
86
|
+
const siteConfig = this.createSiteConfig(outputDir, locale.id, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n);
|
|
87
|
+
// eslint-disable-next-line no-await-in-loop
|
|
88
|
+
await generateUrl(uri, siteConfig);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
// Handle _additionalModules specifiers
|
|
92
|
+
const { _additionalModules } = staticSiteGenerator;
|
|
93
|
+
if (_additionalModules) {
|
|
94
|
+
for (const specifier of _additionalModules) {
|
|
95
|
+
logger.debug(`[SSG] Additional Module: ${locale.id} ${specifier}`);
|
|
96
|
+
const startTime = performance.now();
|
|
97
|
+
const siteConfig = this.createSiteConfig(outputDir, locale.id, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n);
|
|
98
|
+
// eslint-disable-next-line no-await-in-loop
|
|
99
|
+
await this.dispatchJSResourceRecursive(specifier, dispatcher, siteConfig, true);
|
|
100
|
+
// Capture any additional collected metadata
|
|
101
|
+
// eslint-disable-next-line no-await-in-loop
|
|
102
|
+
await this.captureAdditionalRouteMetadata(siteConfig);
|
|
103
|
+
const endTime = performance.now();
|
|
104
|
+
const timeDiff = endTime - startTime;
|
|
105
|
+
logger.info(`[SSG] Additional Module ${locale.id} ${specifier} in ${Math.round(timeDiff)} ms`);
|
|
93
106
|
}
|
|
94
107
|
}
|
|
95
108
|
}
|
|
@@ -233,7 +246,10 @@ export default class SiteGenerator {
|
|
|
233
246
|
}
|
|
234
247
|
addBundleToSiteMetadata(bundleDefinition, url, siteConfig) {
|
|
235
248
|
if (siteConfig.siteMetadata) {
|
|
236
|
-
const
|
|
249
|
+
const locale = siteConfig.locale;
|
|
250
|
+
const specifier = siteConfig.i18n.defaultLocale === locale
|
|
251
|
+
? bundleDefinition.specifier
|
|
252
|
+
: `${bundleDefinition.specifier}|l/${locale}`;
|
|
237
253
|
const imports = bundleDefinition.bundleRecord.imports?.map((moduleRef) => getSpecifier(moduleRef)) || [];
|
|
238
254
|
const bundleMetadata = {
|
|
239
255
|
version: bundleDefinition.version,
|
|
@@ -343,24 +359,15 @@ export default class SiteGenerator {
|
|
|
343
359
|
directoryPath = url.substring(0, lastPathIndex);
|
|
344
360
|
}
|
|
345
361
|
const dir = createResourceDir(directoryPath, outputDir);
|
|
346
|
-
const localeDir = createResourceDir(directoryPath, join(outputDir, siteConfig.locale));
|
|
347
362
|
// TODO: Should we handle routes with non-html extensions differently?
|
|
348
363
|
// Example Route: "path": "/mixed_templates.md" (not sure why you would do this)
|
|
349
364
|
// "contentTemplate": "$contentDir/composed_markdown.md"
|
|
350
365
|
// Today this will get written to /mixed_templates.md/index.html
|
|
351
366
|
// Which we workaround by setting "renderSingle": true in serve.json
|
|
352
367
|
const filePath = join(dir, fileName);
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (siteConfig.locale.toLowerCase().startsWith('en')) {
|
|
357
|
-
siteConfig.viewPaths.add(filePath);
|
|
358
|
-
await writeResponse(context, filePath);
|
|
359
|
-
}
|
|
360
|
-
// Language path (always write out)
|
|
361
|
-
createDir(localeDir);
|
|
362
|
-
siteConfig.viewPaths.add(fileLocalePath);
|
|
363
|
-
await writeResponse(context, fileLocalePath);
|
|
368
|
+
// Write out response
|
|
369
|
+
siteConfig.viewPaths.add(filePath);
|
|
370
|
+
await writeResponse(context, filePath);
|
|
364
371
|
}
|
|
365
372
|
// Get the metadata
|
|
366
373
|
const viewDefinition = context.fs?.metadata?.viewDefinition;
|
|
@@ -549,7 +556,7 @@ export default class SiteGenerator {
|
|
|
549
556
|
const { basePath } = config;
|
|
550
557
|
const runtimeEnvironment = getRuntimeEnvironment(config);
|
|
551
558
|
const siteConfig = this.createSiteConfig(outputDir, 'en-US', // Copy Assets should not use the locale
|
|
552
|
-
new Map(), true, runtimeEnvironment);
|
|
559
|
+
new Map(), true, runtimeEnvironment, config.i18n);
|
|
553
560
|
for (const asset of assets) {
|
|
554
561
|
try {
|
|
555
562
|
const assetSrcFile = asset.file;
|
|
@@ -614,14 +621,14 @@ export default class SiteGenerator {
|
|
|
614
621
|
this.addAssetToSiteMetadata({
|
|
615
622
|
uri,
|
|
616
623
|
type: 'asset',
|
|
617
|
-
stream: function (
|
|
624
|
+
stream: function (_encoding) {
|
|
618
625
|
throw new Error('Function not implemented.');
|
|
619
626
|
},
|
|
620
627
|
entry: filePath,
|
|
621
628
|
ext: extname(filePath),
|
|
622
629
|
mime: mimeLookup(filePath),
|
|
623
630
|
ownHash: 'not-provided',
|
|
624
|
-
content: function (
|
|
631
|
+
content: function (_encoding) {
|
|
625
632
|
throw new Error('Function not implemented.');
|
|
626
633
|
},
|
|
627
634
|
}, uri, siteConfig);
|
|
@@ -633,7 +640,7 @@ export default class SiteGenerator {
|
|
|
633
640
|
/**
|
|
634
641
|
* Create a new site config for the current view
|
|
635
642
|
*/
|
|
636
|
-
createSiteConfig(outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment) {
|
|
643
|
+
createSiteConfig(outputDir, locale, urlRewriteMap, skipBaseDocumentGeneration, runtimeEnvironment, i18n) {
|
|
637
644
|
const featureFlags = this.filterFeatureFlags();
|
|
638
645
|
const endpoints = {
|
|
639
646
|
uris: {
|
|
@@ -653,6 +660,7 @@ export default class SiteGenerator {
|
|
|
653
660
|
// Only include LEGACY_LOADER if true
|
|
654
661
|
...featureFlags,
|
|
655
662
|
siteMetadata: new SiteMetadataImpl({ rootDir: outputDir }),
|
|
663
|
+
i18n,
|
|
656
664
|
};
|
|
657
665
|
}
|
|
658
666
|
filterFeatureFlags() {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Endpoints, FeatureFlags, ImportMetadata, RenderedAssetReference, SiteMetadata } from '@lwrjs/types';
|
|
1
|
+
import type { Endpoints, FeatureFlags, I18NConfig, ImportMetadata, RenderedAssetReference, SiteMetadata } from '@lwrjs/types';
|
|
2
2
|
export interface BaseResourceContextOpts {
|
|
3
3
|
resourceType: 'route' | 'asset' | 'js' | 'resource' | 'mapping';
|
|
4
4
|
}
|
|
@@ -36,6 +36,7 @@ export interface SiteConfig {
|
|
|
36
36
|
viewPaths: Set<string>;
|
|
37
37
|
visitedUrls: Set<string>;
|
|
38
38
|
locale: string;
|
|
39
|
+
i18n: I18NConfig;
|
|
39
40
|
urlRewriteMap: Map<string, string>;
|
|
40
41
|
endpoints?: Endpoints;
|
|
41
42
|
importMetadata?: ViewImportMetadata;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import http from 'http';
|
|
2
2
|
import https from 'https';
|
|
3
|
-
import {
|
|
3
|
+
import { logger, DEBUG, VERBOSE } from '@lwrjs/diagnostics';
|
|
4
|
+
import { isModuleOrBundleUrl } from '@lwrjs/shared-utils';
|
|
4
5
|
export default class NetworkDispatcher {
|
|
5
6
|
constructor(port, internalRequestKey) {
|
|
6
7
|
this.port = port || 3000;
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.11.0-alpha.
|
|
7
|
+
"version": "0.11.0-alpha.11",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -39,31 +39,33 @@
|
|
|
39
39
|
"build": "tsc -b"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@lwrjs/app-service": "0.11.0-alpha.
|
|
43
|
-
"@lwrjs/asset-registry": "0.11.0-alpha.
|
|
44
|
-
"@lwrjs/asset-transformer": "0.11.0-alpha.
|
|
45
|
-
"@lwrjs/base-view-provider": "0.11.0-alpha.
|
|
46
|
-
"@lwrjs/base-view-transformer": "0.11.0-alpha.
|
|
47
|
-
"@lwrjs/client-modules": "0.11.0-alpha.
|
|
48
|
-
"@lwrjs/config": "0.11.0-alpha.
|
|
49
|
-
"@lwrjs/diagnostics": "0.11.0-alpha.
|
|
50
|
-
"@lwrjs/
|
|
51
|
-
"@lwrjs/
|
|
52
|
-
"@lwrjs/
|
|
53
|
-
"@lwrjs/
|
|
54
|
-
"@lwrjs/
|
|
55
|
-
"@lwrjs/
|
|
56
|
-
"@lwrjs/module-
|
|
57
|
-
"@lwrjs/
|
|
58
|
-
"@lwrjs/
|
|
59
|
-
"@lwrjs/
|
|
60
|
-
"@lwrjs/
|
|
61
|
-
"@lwrjs/
|
|
62
|
-
"@lwrjs/
|
|
63
|
-
"@lwrjs/
|
|
64
|
-
"@lwrjs/
|
|
65
|
-
"@lwrjs/
|
|
66
|
-
"@lwrjs/
|
|
42
|
+
"@lwrjs/app-service": "0.11.0-alpha.11",
|
|
43
|
+
"@lwrjs/asset-registry": "0.11.0-alpha.11",
|
|
44
|
+
"@lwrjs/asset-transformer": "0.11.0-alpha.11",
|
|
45
|
+
"@lwrjs/base-view-provider": "0.11.0-alpha.11",
|
|
46
|
+
"@lwrjs/base-view-transformer": "0.11.0-alpha.11",
|
|
47
|
+
"@lwrjs/client-modules": "0.11.0-alpha.11",
|
|
48
|
+
"@lwrjs/config": "0.11.0-alpha.11",
|
|
49
|
+
"@lwrjs/diagnostics": "0.11.0-alpha.11",
|
|
50
|
+
"@lwrjs/esbuild": "0.11.0-alpha.11",
|
|
51
|
+
"@lwrjs/fs-asset-provider": "0.11.0-alpha.11",
|
|
52
|
+
"@lwrjs/fs-watch": "0.11.0-alpha.11",
|
|
53
|
+
"@lwrjs/html-view-provider": "0.11.0-alpha.11",
|
|
54
|
+
"@lwrjs/instrumentation": "0.11.0-alpha.11",
|
|
55
|
+
"@lwrjs/loader": "0.11.0-alpha.11",
|
|
56
|
+
"@lwrjs/lwc-module-provider": "0.11.0-alpha.11",
|
|
57
|
+
"@lwrjs/markdown-view-provider": "0.11.0-alpha.11",
|
|
58
|
+
"@lwrjs/module-bundler": "0.11.0-alpha.11",
|
|
59
|
+
"@lwrjs/module-registry": "0.11.0-alpha.11",
|
|
60
|
+
"@lwrjs/npm-module-provider": "0.11.0-alpha.11",
|
|
61
|
+
"@lwrjs/nunjucks-view-provider": "0.11.0-alpha.11",
|
|
62
|
+
"@lwrjs/o11y": "0.11.0-alpha.11",
|
|
63
|
+
"@lwrjs/resource-registry": "0.11.0-alpha.11",
|
|
64
|
+
"@lwrjs/router": "0.11.0-alpha.11",
|
|
65
|
+
"@lwrjs/server": "0.11.0-alpha.11",
|
|
66
|
+
"@lwrjs/shared-utils": "0.11.0-alpha.11",
|
|
67
|
+
"@lwrjs/static": "0.11.0-alpha.11",
|
|
68
|
+
"@lwrjs/view-registry": "0.11.0-alpha.11",
|
|
67
69
|
"chokidar": "^3.5.3",
|
|
68
70
|
"esbuild": "^0.9.7",
|
|
69
71
|
"fs-extra": "^11.1.1",
|
|
@@ -73,11 +75,11 @@
|
|
|
73
75
|
"ws": "^8.8.1"
|
|
74
76
|
},
|
|
75
77
|
"devDependencies": {
|
|
76
|
-
"@lwrjs/types": "0.11.0-alpha.
|
|
78
|
+
"@lwrjs/types": "0.11.0-alpha.11",
|
|
77
79
|
"@types/ws": "^8.5.3"
|
|
78
80
|
},
|
|
79
81
|
"peerDependencies": {
|
|
80
|
-
"lwc": "2.x || 3.x"
|
|
82
|
+
"lwc": "2.x || 3.x || 4.x"
|
|
81
83
|
},
|
|
82
84
|
"engines": {
|
|
83
85
|
"node": ">=16.0.0"
|
|
@@ -85,5 +87,5 @@
|
|
|
85
87
|
"volta": {
|
|
86
88
|
"extends": "../../../package.json"
|
|
87
89
|
},
|
|
88
|
-
"gitHead": "
|
|
90
|
+
"gitHead": "acb9df6ee7887b683e28ad43e00df311256d6018"
|
|
89
91
|
}
|