@lwrjs/core 0.6.0-alpha.7 → 0.6.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/hooks.cjs +10 -1
- package/build/cjs/env-config.cjs +28 -5
- package/build/cjs/index.cjs +13 -0
- package/build/cjs/middlewares/api-middleware.cjs +6 -16
- package/build/cjs/tools/static-generation.cjs +23 -6
- package/build/es/context/hooks.js +13 -1
- package/build/es/env-config.js +35 -5
- package/build/es/index.d.ts +2 -1
- package/build/es/index.js +17 -0
- package/build/es/middlewares/api-middleware.js +11 -20
- package/build/es/tools/static-generation.js +41 -10
- package/build/es/tools/types.d.ts +1 -0
- package/package.json +28 -27
|
@@ -39,7 +39,16 @@ async function runConfigurationsHook(hookPlugins, lwrConfig, dataConfig, runtime
|
|
|
39
39
|
for (const hookPlugin of hookPlugins) {
|
|
40
40
|
await hookPlugin.initConfigs(lwrConfig, dataConfig, runtimeConfig);
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
try {
|
|
43
|
+
(0, import_app_config.validateLwrAppConfig)(JSON.stringify(lwrConfig), "post");
|
|
44
|
+
} catch (e) {
|
|
45
|
+
if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === "true") {
|
|
46
|
+
console.warn("ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution");
|
|
47
|
+
console.dir(e, {depth: null});
|
|
48
|
+
} else {
|
|
49
|
+
throw e;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
43
52
|
normalizeRoutesBootstrap(lwrConfig);
|
|
44
53
|
return {
|
|
45
54
|
lwrConfig,
|
package/build/cjs/env-config.cjs
CHANGED
|
@@ -76,10 +76,17 @@ var DEFAULT_LWR_MODULES = [
|
|
|
76
76
|
{npm: getLWCEngineSpecifier()},
|
|
77
77
|
{npm: "@lwrjs/client-modules"},
|
|
78
78
|
{npm: "@lwrjs/loader"},
|
|
79
|
+
{npm: "@lwrjs/o11y"},
|
|
79
80
|
{npm: "@lwrjs/router"},
|
|
80
81
|
{npm: "@lwc/synthetic-shadow"}
|
|
81
82
|
];
|
|
82
|
-
var DEFAULT_BUNDLE_EXCLUSIONS = [
|
|
83
|
+
var DEFAULT_BUNDLE_EXCLUSIONS = [
|
|
84
|
+
"lwc",
|
|
85
|
+
"@lwc/synthetic-shadow",
|
|
86
|
+
"lwr/navigation",
|
|
87
|
+
"lwr/esmLoader",
|
|
88
|
+
"lwr/profiler"
|
|
89
|
+
];
|
|
83
90
|
var DEFAULT_LWR_CONFIG = {
|
|
84
91
|
port: PORT,
|
|
85
92
|
ignoreLwrConfigFile: false,
|
|
@@ -119,11 +126,18 @@ function createCacheFolder(cache, rootDir) {
|
|
|
119
126
|
function getLwrConfigFromFile(rootDir, customDir = DEFAULT_LWR_CONFIG_JSON) {
|
|
120
127
|
const lwrConfigPath = import_path.default.resolve((0, import_shared_utils.normalizeDirectory)(customDir, rootDir));
|
|
121
128
|
if (import_fs.default.existsSync(lwrConfigPath)) {
|
|
129
|
+
const configAsString = (0, import_shared_utils.readFile)(lwrConfigPath);
|
|
122
130
|
try {
|
|
123
|
-
return (0, import_app_config.validateLwrAppConfig)(
|
|
131
|
+
return (0, import_app_config.validateLwrAppConfig)(configAsString, "file");
|
|
124
132
|
} catch (e) {
|
|
125
133
|
if (e instanceof import_diagnostics.LwrConfigValidationError) {
|
|
126
|
-
|
|
134
|
+
if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === "true") {
|
|
135
|
+
console.warn("ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution");
|
|
136
|
+
console.dir(e, {depth: null});
|
|
137
|
+
return JSON.parse(configAsString);
|
|
138
|
+
} else {
|
|
139
|
+
throw e;
|
|
140
|
+
}
|
|
127
141
|
}
|
|
128
142
|
return void 0;
|
|
129
143
|
}
|
|
@@ -216,7 +230,7 @@ function mergeLWCConfigs(config1, config2) {
|
|
|
216
230
|
};
|
|
217
231
|
}
|
|
218
232
|
function mergeBundleConfig(jsonConfig, config) {
|
|
219
|
-
const defaultExclusions = DEFAULT_BUNDLE_EXCLUSIONS;
|
|
233
|
+
const defaultExclusions = config?.bundleConfig?.UNSAFE_lwrDefaultExclude || jsonConfig?.bundleConfig?.UNSAFE_lwrDefaultExclude || DEFAULT_BUNDLE_EXCLUSIONS;
|
|
220
234
|
const configExclusions = config?.bundleConfig?.exclude || jsonConfig?.bundleConfig?.exclude || [];
|
|
221
235
|
return {
|
|
222
236
|
...jsonConfig?.bundleConfig,
|
|
@@ -258,7 +272,16 @@ function trimLwrConfig(config) {
|
|
|
258
272
|
function normalizeConfig(config) {
|
|
259
273
|
if (config !== void 0) {
|
|
260
274
|
config = trimLwrConfig(config);
|
|
261
|
-
|
|
275
|
+
try {
|
|
276
|
+
(0, import_app_config.validateLwrAppConfig)(JSON.stringify(config), "pre");
|
|
277
|
+
} catch (e) {
|
|
278
|
+
if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === "true") {
|
|
279
|
+
console.warn("ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution");
|
|
280
|
+
console.dir(e, {depth: null});
|
|
281
|
+
} else {
|
|
282
|
+
throw e;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
262
285
|
}
|
|
263
286
|
const rootDir = import_path.default.resolve(config?.rootDir || DEFAULT_ROOT_DIR);
|
|
264
287
|
const lwrJsonConfig = config?.ignoreLwrConfigFile === true ? void 0 : getLwrConfigFromFile(rootDir, config?.lwrConfigFile);
|
package/build/cjs/index.cjs
CHANGED
|
@@ -229,6 +229,15 @@ var LwrApp = class {
|
|
|
229
229
|
getInternalServer() {
|
|
230
230
|
return this.app.getImpl();
|
|
231
231
|
}
|
|
232
|
+
getServer() {
|
|
233
|
+
return {
|
|
234
|
+
use: this.app.use.bind(this.app),
|
|
235
|
+
all: this.app.all.bind(this.app),
|
|
236
|
+
get: this.app.get.bind(this.app),
|
|
237
|
+
post: this.app.post.bind(this.app),
|
|
238
|
+
getRegexWildcard: this.app.getRegexWildcard.bind(this.app)
|
|
239
|
+
};
|
|
240
|
+
}
|
|
232
241
|
};
|
|
233
242
|
function createServer(config) {
|
|
234
243
|
return new LwrApp(config);
|
|
@@ -236,6 +245,10 @@ function createServer(config) {
|
|
|
236
245
|
async function generateStaticSite(config) {
|
|
237
246
|
config = config || {};
|
|
238
247
|
config.serverType = "fs";
|
|
248
|
+
const {serverMode} = config;
|
|
249
|
+
if (serverMode === "dev" || serverMode === "compat") {
|
|
250
|
+
console.warn("[WARN] static generation in `dev` or `compat` mode is currently not fully supported");
|
|
251
|
+
}
|
|
239
252
|
const lwrApp = createServer(config);
|
|
240
253
|
overrideConfigAsSrc(lwrApp);
|
|
241
254
|
await lwrApp.init();
|
|
@@ -127,17 +127,12 @@ function apiMiddleware(app, context) {
|
|
|
127
127
|
const {entry} = await moduleRegistry.getModuleEntry(importerModuleId);
|
|
128
128
|
moduleId = {...moduleId, importer: entry};
|
|
129
129
|
}
|
|
130
|
-
const {format, compat, locale, apiVersion} = req.params;
|
|
131
130
|
const {ownHash, moduleEntry} = await moduleRegistry.getModule(moduleId, ctx.runtimeParams);
|
|
132
131
|
if (ownHash) {
|
|
133
|
-
const
|
|
134
|
-
const
|
|
135
|
-
specifier: moduleEntry.specifier,
|
|
136
|
-
version: (0, import_shared_utils.normalizeVersionToUri)(moduleEntry.version)
|
|
137
|
-
}));
|
|
138
|
-
const jsonQuery = req.isJsonRequest() ? "?json" : "";
|
|
132
|
+
const jsonQuery = req.isJsonRequest() ? `${ctx.runtimeEnvironment.debug ? "&" : "?"}json` : "";
|
|
133
|
+
const uri = await moduleRegistry.resolveModuleUri({...moduleId, version: moduleEntry.version}, ctx.runtimeEnvironment, ctx.runtimeParams, ownHash);
|
|
139
134
|
res.set({
|
|
140
|
-
Location:
|
|
135
|
+
Location: `${uri}${jsonQuery}`
|
|
141
136
|
});
|
|
142
137
|
res.sendStatus(302);
|
|
143
138
|
}
|
|
@@ -241,17 +236,12 @@ function apiMiddleware(app, context) {
|
|
|
241
236
|
const {entry} = await moduleRegistry.getModuleEntry(importerModuleId);
|
|
242
237
|
moduleId = {...moduleId, importer: entry};
|
|
243
238
|
}
|
|
244
|
-
const {format, compat, locale, apiVersion} = req.params;
|
|
245
239
|
const {ownHash, moduleEntry} = await moduleRegistry.getModule(moduleId, ctx.runtimeParams);
|
|
246
240
|
if (ownHash) {
|
|
247
|
-
const
|
|
248
|
-
const
|
|
249
|
-
specifier: moduleEntry.specifier,
|
|
250
|
-
version: (0, import_shared_utils.normalizeVersionToUri)(moduleEntry.version)
|
|
251
|
-
}));
|
|
252
|
-
const jsonQuery = req.isJsonRequest() ? "?json" : "";
|
|
241
|
+
const jsonQuery = req.isJsonRequest() ? `${ctx.runtimeEnvironment.debug ? "&" : "?"}json` : "";
|
|
242
|
+
const uri = await moduleRegistry.resolveModuleUri({...moduleId, version: moduleEntry.version}, ctx.runtimeEnvironment, ctx.runtimeParams, ownHash);
|
|
253
243
|
res.set({
|
|
254
|
-
Location:
|
|
244
|
+
Location: `${uri}${jsonQuery}`
|
|
255
245
|
});
|
|
256
246
|
res.sendStatus(302);
|
|
257
247
|
}
|
|
@@ -108,20 +108,21 @@ var SiteGenerator = class {
|
|
|
108
108
|
await (0, import_stream.writeResponse)(context, fullPath);
|
|
109
109
|
const dispatchRequests = [];
|
|
110
110
|
if (normalizedUrl.indexOf("/s/") !== -1) {
|
|
111
|
-
|
|
112
|
-
siteConfig.urlRewriteMap.set(rewriteUrl, normalizedUrl);
|
|
111
|
+
siteConfig.urlRewriteMap.set(normalizedUrl.substring(0, normalizedUrl.indexOf("/s/")), normalizedUrl);
|
|
113
112
|
siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf("/s/")), normalizedUrl);
|
|
113
|
+
siteConfig.urlRewriteMap.set(normalizedUrl.substring(0, normalizedUrl.indexOf("/v/")), normalizedUrl);
|
|
114
|
+
siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf("%2Fv%2F")), normalizedUrl);
|
|
114
115
|
}
|
|
115
116
|
const moduleDefinition = context.fs?.metadata?.moduleDefinition;
|
|
116
117
|
if (moduleDefinition) {
|
|
117
118
|
const imports = moduleDefinition.linkedModuleRecord?.imports || moduleDefinition.bundleRecord?.imports || [];
|
|
118
119
|
for (const importModule of imports) {
|
|
119
|
-
const jsUri = (0, import_shared_utils.getSpecifier)(importModule);
|
|
120
|
+
const jsUri = importModule.specifier.startsWith("/") ? importModule.specifier : (0, import_shared_utils.getSpecifier)(importModule);
|
|
120
121
|
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
121
122
|
}
|
|
122
123
|
const dynamicImports = moduleDefinition.linkedModuleRecord?.dynamicImports || moduleDefinition.bundleRecord?.dynamicImports || [];
|
|
123
124
|
for (const importModule of dynamicImports) {
|
|
124
|
-
const jsUri = (0, import_shared_utils.getSpecifier)(importModule);
|
|
125
|
+
const jsUri = importModule.specifier.startsWith("/") ? importModule.specifier : (0, import_shared_utils.getSpecifier)(importModule);
|
|
125
126
|
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
126
127
|
}
|
|
127
128
|
}
|
|
@@ -158,9 +159,11 @@ var SiteGenerator = class {
|
|
|
158
159
|
const filePath = (0, import_path.join)(dir, "index.html");
|
|
159
160
|
const fileLocalePath = (0, import_path.join)(localeDir, "index.html");
|
|
160
161
|
if (siteConfig.locale.toLowerCase().startsWith("en")) {
|
|
162
|
+
siteConfig.viewPaths.add(filePath);
|
|
161
163
|
await (0, import_stream.writeResponse)(context, filePath);
|
|
162
164
|
}
|
|
163
165
|
(0, import_dir.createDir)(localeDir);
|
|
166
|
+
siteConfig.viewPaths.add(fileLocalePath);
|
|
164
167
|
await (0, import_stream.writeResponse)(context, fileLocalePath);
|
|
165
168
|
const viewDefinition = context.fs?.metadata?.viewDefinition;
|
|
166
169
|
if (viewDefinition) {
|
|
@@ -285,6 +288,7 @@ var SiteGenerator = class {
|
|
|
285
288
|
const experimentalFeatures = this.filterExperimentalFeatures();
|
|
286
289
|
return {
|
|
287
290
|
outputDir,
|
|
291
|
+
viewPaths: new Set(),
|
|
288
292
|
visitedUrls: new Set(),
|
|
289
293
|
locale,
|
|
290
294
|
urlRewriteMap,
|
|
@@ -308,13 +312,26 @@ var SiteGenerator = class {
|
|
|
308
312
|
const index = additionalImportMetadata.index ? JSON.stringify(additionalImportMetadata.index) : "{}";
|
|
309
313
|
const initIndex = `if (!globalThis.LWR.index) { globalThis.LWR.index = {}; }`;
|
|
310
314
|
const mergeIndex = `Object.assign(globalThis.LWR.index, ${index})`;
|
|
311
|
-
import_fs_extra.default.
|
|
315
|
+
const oldConfig = import_fs_extra.default.readFileSync(siteConfig.viewConfigPath, "utf-8");
|
|
316
|
+
const newConfig = `${oldConfig}
|
|
312
317
|
// Appended by Static Site Generator
|
|
313
318
|
${initImports}
|
|
314
319
|
${mergeImports}
|
|
315
320
|
${initIndex}
|
|
316
321
|
${mergeIndex}
|
|
317
|
-
|
|
322
|
+
`;
|
|
323
|
+
const configHash = (0, import_shared_utils.hashContent)(newConfig);
|
|
324
|
+
const sigRegex = /\/s\/[a-z0-9]+\/config\.js/i;
|
|
325
|
+
const configSuffix = `/s/${configHash}/config.js`;
|
|
326
|
+
const newConfigPath = siteConfig.viewConfigPath.replace(sigRegex, configSuffix);
|
|
327
|
+
import_fs_extra.default.mkdirSync((0, import_path.dirname)(newConfigPath), {recursive: true});
|
|
328
|
+
import_fs_extra.default.writeFileSync(newConfigPath, newConfig, "utf-8");
|
|
329
|
+
import_fs_extra.default.rmSync(siteConfig.viewConfigPath);
|
|
330
|
+
siteConfig.viewPaths.forEach((path) => {
|
|
331
|
+
const oldDoc = import_fs_extra.default.readFileSync(path, "utf-8");
|
|
332
|
+
const newDoc = oldDoc.toString().replace(sigRegex, configSuffix);
|
|
333
|
+
import_fs_extra.default.writeFileSync(path, newDoc, "utf-8");
|
|
334
|
+
});
|
|
318
335
|
}
|
|
319
336
|
}
|
|
320
337
|
};
|
|
@@ -13,7 +13,19 @@ export async function runConfigurationsHook(hookPlugins, lwrConfig, dataConfig,
|
|
|
13
13
|
// eslint-disable-next-line no-await-in-loop
|
|
14
14
|
await hookPlugin.initConfigs(lwrConfig, dataConfig, runtimeConfig);
|
|
15
15
|
}
|
|
16
|
-
|
|
16
|
+
try {
|
|
17
|
+
validateLwrAppConfig(JSON.stringify(lwrConfig), 'post');
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
// TODO: temporary workaround for https://github.com/salesforce/lwr/issues/825
|
|
21
|
+
if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === 'true') {
|
|
22
|
+
console.warn('ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution');
|
|
23
|
+
console.dir(e, { depth: null });
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw e;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
17
29
|
normalizeRoutesBootstrap(lwrConfig);
|
|
18
30
|
return {
|
|
19
31
|
lwrConfig,
|
package/build/es/env-config.js
CHANGED
|
@@ -50,10 +50,17 @@ const DEFAULT_LWR_MODULES = [
|
|
|
50
50
|
{ npm: getLWCEngineSpecifier() },
|
|
51
51
|
{ npm: '@lwrjs/client-modules' },
|
|
52
52
|
{ npm: '@lwrjs/loader' },
|
|
53
|
+
{ npm: '@lwrjs/o11y' },
|
|
53
54
|
{ npm: '@lwrjs/router' },
|
|
54
55
|
{ npm: '@lwc/synthetic-shadow' },
|
|
55
56
|
];
|
|
56
|
-
const DEFAULT_BUNDLE_EXCLUSIONS = [
|
|
57
|
+
const DEFAULT_BUNDLE_EXCLUSIONS = [
|
|
58
|
+
'lwc',
|
|
59
|
+
'@lwc/synthetic-shadow',
|
|
60
|
+
'lwr/navigation',
|
|
61
|
+
'lwr/esmLoader',
|
|
62
|
+
'lwr/profiler',
|
|
63
|
+
];
|
|
57
64
|
// Default config objects
|
|
58
65
|
const DEFAULT_LWR_CONFIG = {
|
|
59
66
|
port: PORT,
|
|
@@ -94,12 +101,21 @@ function createCacheFolder(cache, rootDir) {
|
|
|
94
101
|
function getLwrConfigFromFile(rootDir, customDir = DEFAULT_LWR_CONFIG_JSON) {
|
|
95
102
|
const lwrConfigPath = path.resolve(normalizeDirectory(customDir, rootDir));
|
|
96
103
|
if (fs.existsSync(lwrConfigPath)) {
|
|
104
|
+
const configAsString = readFile(lwrConfigPath);
|
|
97
105
|
try {
|
|
98
|
-
return validateLwrAppConfig(
|
|
106
|
+
return validateLwrAppConfig(configAsString, 'file');
|
|
99
107
|
}
|
|
100
108
|
catch (e) {
|
|
101
109
|
if (e instanceof LwrConfigValidationError) {
|
|
102
|
-
|
|
110
|
+
// TODO: temporary workaround for https://github.com/salesforce/lwr/issues/825
|
|
111
|
+
if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === 'true') {
|
|
112
|
+
console.warn('ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution');
|
|
113
|
+
console.dir(e, { depth: null });
|
|
114
|
+
return JSON.parse(configAsString);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
throw e;
|
|
118
|
+
}
|
|
103
119
|
}
|
|
104
120
|
return undefined;
|
|
105
121
|
}
|
|
@@ -201,7 +217,9 @@ function mergeLWCConfigs(config1, config2) {
|
|
|
201
217
|
}
|
|
202
218
|
// merge default bundle exclusions with any bundle exclusions specified in config
|
|
203
219
|
function mergeBundleConfig(jsonConfig, config) {
|
|
204
|
-
const defaultExclusions =
|
|
220
|
+
const defaultExclusions = config?.bundleConfig?.UNSAFE_lwrDefaultExclude ||
|
|
221
|
+
jsonConfig?.bundleConfig?.UNSAFE_lwrDefaultExclude ||
|
|
222
|
+
DEFAULT_BUNDLE_EXCLUSIONS;
|
|
205
223
|
const configExclusions = config?.bundleConfig?.exclude || jsonConfig?.bundleConfig?.exclude || [];
|
|
206
224
|
return {
|
|
207
225
|
...jsonConfig?.bundleConfig,
|
|
@@ -259,7 +277,19 @@ function trimLwrConfig(config) {
|
|
|
259
277
|
export function normalizeConfig(config) {
|
|
260
278
|
if (config !== undefined) {
|
|
261
279
|
config = trimLwrConfig(config);
|
|
262
|
-
|
|
280
|
+
try {
|
|
281
|
+
validateLwrAppConfig(JSON.stringify(config), 'pre');
|
|
282
|
+
}
|
|
283
|
+
catch (e) {
|
|
284
|
+
// TODO: temporary workaround for https://github.com/salesforce/lwr/issues/825
|
|
285
|
+
if (process.env.UNSAFE_IGNORE_CONFIG_VALIDATION === 'true') {
|
|
286
|
+
console.warn('ignoring config validation errors due to UNSAFE_IGNORE_CONFIG_VALIDATION flag...proceed with caution');
|
|
287
|
+
console.dir(e, { depth: null });
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
throw e;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
263
293
|
}
|
|
264
294
|
// Merge all configurations together, and return
|
|
265
295
|
const rootDir = path.resolve(config?.rootDir || DEFAULT_ROOT_DIR);
|
package/build/es/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { LwrGlobalConfig, NormalizedLwrGlobalConfig, ServerTypeImpl, ServerTypes } from '@lwrjs/types';
|
|
1
|
+
import { LwrGlobalConfig, NormalizedLwrGlobalConfig, ServerTypeImpl, PublicAppServer, ServerTypes } from '@lwrjs/types';
|
|
2
2
|
export declare class LwrApp {
|
|
3
3
|
private app;
|
|
4
4
|
private server;
|
|
@@ -14,6 +14,7 @@ export declare class LwrApp {
|
|
|
14
14
|
}) => void) | undefined): Promise<void>;
|
|
15
15
|
close(): Promise<void>;
|
|
16
16
|
getInternalServer<S extends ServerTypes>(): ServerTypeImpl<S>;
|
|
17
|
+
getServer(): PublicAppServer<ServerTypes>;
|
|
17
18
|
}
|
|
18
19
|
export declare function createServer(config?: LwrGlobalConfig): LwrApp;
|
|
19
20
|
export declare function generateStaticSite(config?: LwrGlobalConfig): Promise<void>;
|
package/build/es/index.js
CHANGED
|
@@ -193,9 +193,20 @@ export class LwrApp {
|
|
|
193
193
|
async close() {
|
|
194
194
|
this.server?.close && (await this.server.close());
|
|
195
195
|
}
|
|
196
|
+
// Get the underlying server (e.g. express, koa...)
|
|
196
197
|
getInternalServer() {
|
|
197
198
|
return this.app.getImpl();
|
|
198
199
|
}
|
|
200
|
+
// Return the public server interface which is compatible with all server types
|
|
201
|
+
getServer() {
|
|
202
|
+
return {
|
|
203
|
+
use: this.app.use.bind(this.app),
|
|
204
|
+
all: this.app.all.bind(this.app),
|
|
205
|
+
get: this.app.get.bind(this.app),
|
|
206
|
+
post: this.app.post.bind(this.app),
|
|
207
|
+
getRegexWildcard: this.app.getRegexWildcard.bind(this.app),
|
|
208
|
+
};
|
|
209
|
+
}
|
|
199
210
|
}
|
|
200
211
|
export function createServer(config) {
|
|
201
212
|
return new LwrApp(config);
|
|
@@ -203,6 +214,12 @@ export function createServer(config) {
|
|
|
203
214
|
export async function generateStaticSite(config) {
|
|
204
215
|
config = config || {};
|
|
205
216
|
config.serverType = 'fs'; // override serverType
|
|
217
|
+
const { serverMode } = config;
|
|
218
|
+
if (serverMode === 'dev' || serverMode === 'compat') {
|
|
219
|
+
// TODO: dynamic imports are not generated in dev mode
|
|
220
|
+
// https://github.com/salesforce/lwr/issues/1111
|
|
221
|
+
console.warn('[WARN] static generation in `dev` or `compat` mode is currently not fully supported');
|
|
222
|
+
}
|
|
206
223
|
const lwrApp = createServer(config);
|
|
207
224
|
overrideConfigAsSrc(lwrApp);
|
|
208
225
|
await lwrApp.init();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LwrUnresolvableError, createSingleDiagnosticError as createDiagnostic, descriptions, } from '@lwrjs/diagnostics';
|
|
2
|
-
import { LATEST_SIGNATURE, explodeSpecifier, getImportMetadataMappings,
|
|
2
|
+
import { LATEST_SIGNATURE, explodeSpecifier, getImportMetadataMappings, serializeModuleToJson, getModuleIdentity, getResourceIdentity, getAssetIdentity, getMappingIdentity, getVersionedModuleId, } from '@lwrjs/shared-utils';
|
|
3
3
|
import { createReturnStatus, isSupportedEnvironment } from './utils.js';
|
|
4
4
|
export default function apiMiddleware(app, context) {
|
|
5
5
|
const { appConfig: { environment: environmentConfig }, moduleRegistry, moduleBundler, resourceRegistry, runtimeEnvironment: defaultRuntimeEnvironment, } = context;
|
|
@@ -118,20 +118,15 @@ export default function apiMiddleware(app, context) {
|
|
|
118
118
|
const { entry } = await moduleRegistry.getModuleEntry(importerModuleId);
|
|
119
119
|
moduleId = { ...moduleId, importer: entry };
|
|
120
120
|
}
|
|
121
|
-
// const { ownHash, moduleEntry } = await moduleRegistry.getModule(moduleId, ctx.runtimeParams);
|
|
122
|
-
const { format, compat, locale, apiVersion } = req.params;
|
|
123
121
|
const { ownHash, moduleEntry } = await moduleRegistry.getModule(moduleId, ctx.runtimeParams);
|
|
124
122
|
if (ownHash) {
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
})); // get specifier from registry, not req.params
|
|
130
|
-
const jsonQuery = req.isJsonRequest() ? '?json' : '';
|
|
123
|
+
const jsonQuery = req.isJsonRequest()
|
|
124
|
+
? `${ctx.runtimeEnvironment.debug ? '&' : '?'}json`
|
|
125
|
+
: '';
|
|
126
|
+
const uri = await moduleRegistry.resolveModuleUri({ ...moduleId, version: moduleEntry.version }, ctx.runtimeEnvironment, ctx.runtimeParams, ownHash);
|
|
131
127
|
res.set({
|
|
132
128
|
// This redirects to a signed URI
|
|
133
|
-
|
|
134
|
-
Location: `/${apiVersion}/bundle/${format}/${compat}${localeSegment}/bi/0/module/mi/${uriSpecifier}/s/${ownHash}/${moduleId.specifier.replace(/\//g, '_')}${jsonQuery}`,
|
|
129
|
+
Location: `${uri}${jsonQuery}`,
|
|
135
130
|
});
|
|
136
131
|
res.sendStatus(302);
|
|
137
132
|
}
|
|
@@ -261,19 +256,15 @@ export default function apiMiddleware(app, context) {
|
|
|
261
256
|
moduleId = { ...moduleId, importer: entry };
|
|
262
257
|
}
|
|
263
258
|
// Get the module's signature from the registry
|
|
264
|
-
const { format, compat, locale, apiVersion } = req.params;
|
|
265
259
|
const { ownHash, moduleEntry } = await moduleRegistry.getModule(moduleId, ctx.runtimeParams);
|
|
266
260
|
if (ownHash) {
|
|
267
|
-
const
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
})); // get specifier from registry, not req.params
|
|
272
|
-
const jsonQuery = req.isJsonRequest() ? '?json' : '';
|
|
261
|
+
const jsonQuery = req.isJsonRequest()
|
|
262
|
+
? `${ctx.runtimeEnvironment.debug ? '&' : '?'}json`
|
|
263
|
+
: '';
|
|
264
|
+
const uri = await moduleRegistry.resolveModuleUri({ ...moduleId, version: moduleEntry.version }, ctx.runtimeEnvironment, ctx.runtimeParams, ownHash);
|
|
273
265
|
res.set({
|
|
274
266
|
// This redirects to a signed URI
|
|
275
|
-
|
|
276
|
-
Location: `/${apiVersion}/module/${format}/${compat}${localeSegment}/mi/${uriSpecifier}/s/${ownHash}/${moduleId.specifier.replace(/\//g, '_')}${jsonQuery}`,
|
|
267
|
+
Location: `${uri}${jsonQuery}`,
|
|
277
268
|
});
|
|
278
269
|
res.sendStatus(302);
|
|
279
270
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getSpecifier, getExperimentalFeatures } from '@lwrjs/shared-utils';
|
|
1
|
+
import { getSpecifier, getExperimentalFeatures, hashContent } from '@lwrjs/shared-utils';
|
|
2
2
|
import { join, dirname, extname } from 'path';
|
|
3
3
|
import fs from 'fs-extra';
|
|
4
4
|
import { writeResponse } from './utils/stream.js';
|
|
@@ -129,13 +129,20 @@ export default class SiteGenerator {
|
|
|
129
129
|
const dispatchRequests = [];
|
|
130
130
|
// Add URL re-writes for module redirects
|
|
131
131
|
if (normalizedUrl.indexOf('/s/') !== -1) {
|
|
132
|
-
|
|
133
|
-
//
|
|
134
|
-
siteConfig.urlRewriteMap.set(
|
|
135
|
-
// Redirect
|
|
132
|
+
// Redirect unsigned to signed URIs
|
|
133
|
+
// e.g. /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6 -> /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6/s/{signature}
|
|
134
|
+
siteConfig.urlRewriteMap.set(normalizedUrl.substring(0, normalizedUrl.indexOf('/s/')), normalizedUrl);
|
|
135
|
+
// Redirect encoded signed URIs to UNencoded signed URIs
|
|
136
|
+
// e.g. /1/bundle/amd/l/en-US/bi/0/module/mi/c%2Fmodule%2Fv%2F0_1_6/s/{signature} -> /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6/s/{signature}
|
|
136
137
|
siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf('/s/')), normalizedUrl);
|
|
137
|
-
//
|
|
138
|
-
//
|
|
138
|
+
// Redirect unversioned/unsigned URIs to signed URIs
|
|
139
|
+
// e.g. /1/bundle/amd/l/en-US/bi/0/module/mi/c/module -> /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6/s/{signature}
|
|
140
|
+
// e.g. with importer /1/bundle/amd/l/en-US/bi/0/module/mi/c/module?importer=parent%2Fmodule%2Fv%2F2_1_0 -> /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6/s/{signature}
|
|
141
|
+
siteConfig.urlRewriteMap.set(normalizedUrl.substring(0, normalizedUrl.indexOf('/v/')), normalizedUrl);
|
|
142
|
+
// Redirect encoded unversioned/unsigned URIs to UNencoded signed URIs
|
|
143
|
+
// e.g. /1/bundle/amd/l/en-US/bi/0/module/mi/c%2Fmodule -> /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6/s/{signature}
|
|
144
|
+
// e.g. with importer /1/bundle/amd/l/en-US/bi/0/module/mi/c%2Fmodule?importer=parent%2Fmodule%2Fv%2F2_1_0 -> /1/bundle/amd/l/en-US/bi/0/module/mi/c/module/v/0_1_6/s/{signature}
|
|
145
|
+
siteConfig.urlRewriteMap.set(url.substring(0, url.indexOf('%2Fv%2F')), normalizedUrl);
|
|
139
146
|
}
|
|
140
147
|
// Recursively traverse dependencies
|
|
141
148
|
const moduleDefinition = context.fs?.metadata?.moduleDefinition; // LinkedModuleDefinition | BundleDefinition
|
|
@@ -144,7 +151,9 @@ export default class SiteGenerator {
|
|
|
144
151
|
const imports = moduleDefinition.linkedModuleRecord?.imports || moduleDefinition.bundleRecord?.imports || [];
|
|
145
152
|
// /1/module/esm/0/l/en-US/mi/lwc
|
|
146
153
|
for (const importModule of imports) {
|
|
147
|
-
const jsUri =
|
|
154
|
+
const jsUri = importModule.specifier.startsWith('/')
|
|
155
|
+
? importModule.specifier
|
|
156
|
+
: getSpecifier(importModule);
|
|
148
157
|
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
149
158
|
}
|
|
150
159
|
// Dynamic imports
|
|
@@ -152,7 +161,9 @@ export default class SiteGenerator {
|
|
|
152
161
|
moduleDefinition.bundleRecord?.dynamicImports ||
|
|
153
162
|
[];
|
|
154
163
|
for (const importModule of dynamicImports) {
|
|
155
|
-
const jsUri =
|
|
164
|
+
const jsUri = importModule.specifier.startsWith('/')
|
|
165
|
+
? importModule.specifier
|
|
166
|
+
: getSpecifier(importModule);
|
|
156
167
|
dispatchRequests.push(this.dispatchJSResourceRecursive(jsUri, dispatcher, siteConfig));
|
|
157
168
|
}
|
|
158
169
|
}
|
|
@@ -219,10 +230,12 @@ export default class SiteGenerator {
|
|
|
219
230
|
// Default Path (only write once)
|
|
220
231
|
// The default locale is english
|
|
221
232
|
if (siteConfig.locale.toLowerCase().startsWith('en')) {
|
|
233
|
+
siteConfig.viewPaths.add(filePath);
|
|
222
234
|
await writeResponse(context, filePath);
|
|
223
235
|
}
|
|
224
236
|
// Language path (always write out)
|
|
225
237
|
createDir(localeDir);
|
|
238
|
+
siteConfig.viewPaths.add(fileLocalePath);
|
|
226
239
|
await writeResponse(context, fileLocalePath);
|
|
227
240
|
// Get the metadata
|
|
228
241
|
const viewDefinition = context.fs?.metadata?.viewDefinition;
|
|
@@ -407,6 +420,7 @@ export default class SiteGenerator {
|
|
|
407
420
|
const experimentalFeatures = this.filterExperimentalFeatures();
|
|
408
421
|
return {
|
|
409
422
|
outputDir,
|
|
423
|
+
viewPaths: new Set(),
|
|
410
424
|
visitedUrls: new Set(),
|
|
411
425
|
locale,
|
|
412
426
|
urlRewriteMap,
|
|
@@ -432,6 +446,7 @@ export default class SiteGenerator {
|
|
|
432
446
|
siteConfig.viewConfigPath &&
|
|
433
447
|
additionalImportMetadata?.imports &&
|
|
434
448
|
Object.keys(additionalImportMetadata.imports).length > 0) {
|
|
449
|
+
// Build and stringify the new import metadata
|
|
435
450
|
const imports = additionalImportMetadata.imports
|
|
436
451
|
? JSON.stringify(additionalImportMetadata.imports)
|
|
437
452
|
: '{}';
|
|
@@ -442,7 +457,23 @@ export default class SiteGenerator {
|
|
|
442
457
|
: '{}';
|
|
443
458
|
const initIndex = `if (!globalThis.LWR.index) { globalThis.LWR.index = {}; }`;
|
|
444
459
|
const mergeIndex = `Object.assign(globalThis.LWR.index, ${index})`;
|
|
445
|
-
|
|
460
|
+
// Read in the old config and append the new import metadata
|
|
461
|
+
const oldConfig = fs.readFileSync(siteConfig.viewConfigPath, 'utf-8');
|
|
462
|
+
const newConfig = `${oldConfig}\n// Appended by Static Site Generator\n${initImports}\n${mergeImports}\n${initIndex}\n${mergeIndex}\n`;
|
|
463
|
+
const configHash = hashContent(newConfig);
|
|
464
|
+
// Write the updated config to a new filepath containing its hash signature, and delete the old config
|
|
465
|
+
const sigRegex = /\/s\/[a-z0-9]+\/config\.js/i;
|
|
466
|
+
const configSuffix = `/s/${configHash}/config.js`;
|
|
467
|
+
const newConfigPath = siteConfig.viewConfigPath.replace(sigRegex, configSuffix);
|
|
468
|
+
fs.mkdirSync(dirname(newConfigPath), { recursive: true }); // we know this dir does not exist
|
|
469
|
+
fs.writeFileSync(newConfigPath, newConfig, 'utf-8');
|
|
470
|
+
fs.rmSync(siteConfig.viewConfigPath);
|
|
471
|
+
// Update the config script src in the view document(s)
|
|
472
|
+
siteConfig.viewPaths.forEach((path) => {
|
|
473
|
+
const oldDoc = fs.readFileSync(path, 'utf-8');
|
|
474
|
+
const newDoc = oldDoc.toString().replace(sigRegex, configSuffix);
|
|
475
|
+
fs.writeFileSync(path, newDoc, 'utf-8');
|
|
476
|
+
});
|
|
446
477
|
}
|
|
447
478
|
}
|
|
448
479
|
}
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
-
"version": "0.6.0
|
|
7
|
+
"version": "0.6.0",
|
|
8
8
|
"homepage": "https://developer.salesforce.com/docs/platform/lwr/overview",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
@@ -33,30 +33,31 @@
|
|
|
33
33
|
"package.cjs"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@lwrjs/app-service": "0.6.0
|
|
37
|
-
"@lwrjs/asset-registry": "0.6.0
|
|
38
|
-
"@lwrjs/asset-transformer": "0.6.0
|
|
39
|
-
"@lwrjs/base-template-engine": "0.6.0
|
|
40
|
-
"@lwrjs/base-view-provider": "0.6.0
|
|
41
|
-
"@lwrjs/base-view-transformer": "0.6.0
|
|
42
|
-
"@lwrjs/client-modules": "0.6.0
|
|
43
|
-
"@lwrjs/compiler": "0.6.0
|
|
44
|
-
"@lwrjs/diagnostics": "0.6.0
|
|
45
|
-
"@lwrjs/fs-asset-provider": "0.6.0
|
|
46
|
-
"@lwrjs/html-view-provider": "0.6.0
|
|
47
|
-
"@lwrjs/loader": "0.6.0
|
|
48
|
-
"@lwrjs/lwc-module-provider": "0.6.0
|
|
49
|
-
"@lwrjs/lwc-ssr": "0.6.0
|
|
50
|
-
"@lwrjs/markdown-view-provider": "0.6.0
|
|
51
|
-
"@lwrjs/module-bundler": "0.6.0
|
|
52
|
-
"@lwrjs/module-registry": "0.6.0
|
|
53
|
-
"@lwrjs/npm-module-provider": "0.6.0
|
|
54
|
-
"@lwrjs/nunjucks-view-provider": "0.6.0
|
|
55
|
-
"@lwrjs/
|
|
56
|
-
"@lwrjs/
|
|
57
|
-
"@lwrjs/
|
|
58
|
-
"@lwrjs/
|
|
59
|
-
"@lwrjs/
|
|
36
|
+
"@lwrjs/app-service": "0.6.0",
|
|
37
|
+
"@lwrjs/asset-registry": "0.6.0",
|
|
38
|
+
"@lwrjs/asset-transformer": "0.6.0",
|
|
39
|
+
"@lwrjs/base-template-engine": "0.6.0",
|
|
40
|
+
"@lwrjs/base-view-provider": "0.6.0",
|
|
41
|
+
"@lwrjs/base-view-transformer": "0.6.0",
|
|
42
|
+
"@lwrjs/client-modules": "0.6.0",
|
|
43
|
+
"@lwrjs/compiler": "0.6.0",
|
|
44
|
+
"@lwrjs/diagnostics": "0.6.0",
|
|
45
|
+
"@lwrjs/fs-asset-provider": "0.6.0",
|
|
46
|
+
"@lwrjs/html-view-provider": "0.6.0",
|
|
47
|
+
"@lwrjs/loader": "0.6.0",
|
|
48
|
+
"@lwrjs/lwc-module-provider": "0.6.0",
|
|
49
|
+
"@lwrjs/lwc-ssr": "0.6.0",
|
|
50
|
+
"@lwrjs/markdown-view-provider": "0.6.0",
|
|
51
|
+
"@lwrjs/module-bundler": "0.6.0",
|
|
52
|
+
"@lwrjs/module-registry": "0.6.0",
|
|
53
|
+
"@lwrjs/npm-module-provider": "0.6.0",
|
|
54
|
+
"@lwrjs/nunjucks-view-provider": "0.6.0",
|
|
55
|
+
"@lwrjs/o11y": "0.6.0",
|
|
56
|
+
"@lwrjs/resource-registry": "0.6.0",
|
|
57
|
+
"@lwrjs/router": "0.6.0",
|
|
58
|
+
"@lwrjs/server": "0.6.0",
|
|
59
|
+
"@lwrjs/shared-utils": "0.6.0",
|
|
60
|
+
"@lwrjs/view-registry": "0.6.0",
|
|
60
61
|
"dompurify": "^2.3.0",
|
|
61
62
|
"fs-extra": "^10.0.0",
|
|
62
63
|
"jsdom": "^16.7.0",
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
"qs": "^6.9.4"
|
|
67
68
|
},
|
|
68
69
|
"devDependencies": {
|
|
69
|
-
"@lwrjs/types": "0.6.0
|
|
70
|
+
"@lwrjs/types": "0.6.0"
|
|
70
71
|
},
|
|
71
72
|
"peerDependencies": {
|
|
72
73
|
"lwc": ">= 1.x <= 2.x"
|
|
@@ -74,5 +75,5 @@
|
|
|
74
75
|
"engines": {
|
|
75
76
|
"node": ">=14.15.4 <17"
|
|
76
77
|
},
|
|
77
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "31769655f0155ad7e54cf37bccdf72d0baaf44ab"
|
|
78
79
|
}
|