@lwrjs/view-registry 0.13.0-alpha.3 → 0.13.0-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/cjs/index.cjs +32 -30
- package/build/cjs/linkers/legacy_view_bootstrap.cjs +35 -12
- package/build/cjs/linkers/preload-utils.cjs +6 -3
- package/build/cjs/linkers/utils.cjs +7 -0
- package/build/cjs/linkers/view_bootstrap.cjs +28 -12
- package/build/cjs/utils.cjs +47 -8
- package/build/cjs/view-handler.cjs +9 -1
- package/build/es/index.d.ts +1 -1
- package/build/es/index.js +41 -34
- package/build/es/linkers/legacy_view_bootstrap.js +43 -14
- package/build/es/linkers/preload-utils.d.ts +2 -1
- package/build/es/linkers/preload-utils.js +8 -5
- package/build/es/linkers/utils.d.ts +2 -1
- package/build/es/linkers/utils.js +9 -0
- package/build/es/linkers/view_bootstrap.js +33 -12
- package/build/es/utils.d.ts +13 -1
- package/build/es/utils.js +53 -8
- package/build/es/view-handler.js +12 -1
- package/package.json +11 -8
package/build/cjs/index.cjs
CHANGED
|
@@ -57,7 +57,7 @@ var LwrViewRegistry = class {
|
|
|
57
57
|
observer.onAssetSourceChange(({payload}) => this.onAssetSourceChange(payload));
|
|
58
58
|
}
|
|
59
59
|
async onModuleDefinitionChange(moduleDefinition) {
|
|
60
|
-
if (
|
|
60
|
+
if ((0, import_shared_utils.isLocalDev)()) {
|
|
61
61
|
this.viewDefinitions.clear();
|
|
62
62
|
return;
|
|
63
63
|
}
|
|
@@ -80,7 +80,7 @@ var LwrViewRegistry = class {
|
|
|
80
80
|
}
|
|
81
81
|
}
|
|
82
82
|
async onViewSourceChange(compiledView) {
|
|
83
|
-
if (
|
|
83
|
+
if ((0, import_shared_utils.isLocalDev)()) {
|
|
84
84
|
this.viewDefinitions.clear();
|
|
85
85
|
return;
|
|
86
86
|
}
|
|
@@ -136,17 +136,15 @@ var LwrViewRegistry = class {
|
|
|
136
136
|
}
|
|
137
137
|
throw new Error(`No View provider was able to resolve a view for template: ${viewId.contentTemplate}`);
|
|
138
138
|
}
|
|
139
|
-
async getView(viewId
|
|
139
|
+
async getView(viewId) {
|
|
140
140
|
const {contentTemplate, rootComponent} = viewId;
|
|
141
141
|
const compiledViewCacheKey = (0, import_shared_utils.getCacheKeyFromJson)({contentTemplate, rootComponent});
|
|
142
142
|
import_diagnostics.logger.debug(`[view-registry][getView] compiledViewCacheKey=${compiledViewCacheKey}`);
|
|
143
|
-
if (
|
|
143
|
+
if (this.compiledViews.has(compiledViewCacheKey)) {
|
|
144
144
|
return this.compiledViews.get(compiledViewCacheKey);
|
|
145
145
|
}
|
|
146
146
|
const compiledView = await this.delegateGetView(viewId);
|
|
147
|
-
|
|
148
|
-
this.compiledViews.set(compiledViewCacheKey, compiledView);
|
|
149
|
-
}
|
|
147
|
+
this.compiledViews.set(compiledViewCacheKey, compiledView);
|
|
150
148
|
return compiledView;
|
|
151
149
|
}
|
|
152
150
|
hasViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions) {
|
|
@@ -161,7 +159,8 @@ var LwrViewRegistry = class {
|
|
|
161
159
|
freezeAssets,
|
|
162
160
|
locale: runtimeParams?.locale,
|
|
163
161
|
basePath: runtimeParams?.basePath,
|
|
164
|
-
debug: runtimeEnvironment.debug
|
|
162
|
+
debug: runtimeEnvironment.debug,
|
|
163
|
+
nonceEnabled: (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE
|
|
165
164
|
});
|
|
166
165
|
import_diagnostics.logger.debug(`[view-registry][hasViewDefinition] viewDefId=${viewDefId}`);
|
|
167
166
|
const viewParamKey = viewParamCacheKey ? (0, import_shared_utils.getCacheKeyFromJson)(viewParamCacheKey) : (0, import_shared_utils.getCacheKeyFromJson)(viewParams);
|
|
@@ -176,24 +175,26 @@ var LwrViewRegistry = class {
|
|
|
176
175
|
}
|
|
177
176
|
async getViewDefinition(view, viewParams, runtimeEnvironment, runtimeParams, renderOptions) {
|
|
178
177
|
try {
|
|
179
|
-
const {
|
|
178
|
+
const {freezeAssets, viewParamCacheKey} = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderOptions);
|
|
180
179
|
const viewDefCacheKey = (0, import_shared_utils.getCacheKeyFromJson)({
|
|
181
180
|
...view,
|
|
182
181
|
freezeAssets,
|
|
183
182
|
locale: runtimeParams?.locale,
|
|
184
183
|
basePath: runtimeParams?.basePath,
|
|
185
|
-
debug: runtimeEnvironment.debug
|
|
184
|
+
debug: runtimeEnvironment.debug,
|
|
185
|
+
nonceEnabled: (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE
|
|
186
186
|
});
|
|
187
187
|
import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewDefCacheKey=${viewDefCacheKey}`);
|
|
188
188
|
const viewParamKey = viewParamCacheKey ? (0, import_shared_utils.getCacheKeyFromJson)(viewParamCacheKey) : (0, import_shared_utils.getCacheKeyFromJson)(viewParams);
|
|
189
189
|
import_diagnostics.logger.debug(`[view-registry][getViewDefinition] viewParamKey=${viewParamKey}`);
|
|
190
|
-
|
|
191
|
-
if (cacheDisabled === false && this.viewDefinitions.has(viewDefCacheKey)) {
|
|
190
|
+
if (this.viewDefinitions.has(viewDefCacheKey)) {
|
|
192
191
|
const viewDefinition2 = this.viewDefinitions.get(viewDefCacheKey);
|
|
193
192
|
if (viewDefinition2 && viewDefinition2.paramKey === viewParamKey && viewDefinition2.viewDefinition.immutable) {
|
|
194
193
|
return viewDefinition2.viewDefinition;
|
|
195
194
|
}
|
|
196
195
|
}
|
|
196
|
+
const updatableViewParams = {...viewParams};
|
|
197
|
+
(0, import_utils.generateViewNonce)(updatableViewParams);
|
|
197
198
|
const pendingViewDefCacheKey = viewDefCacheKey + viewParamKey;
|
|
198
199
|
const viewDefinition = await this.pendingViewDefinitions.execute(pendingViewDefCacheKey, () => (0, import_instrumentation.getTracer)().trace({
|
|
199
200
|
name: import_instrumentation.ViewSpan.RenderView,
|
|
@@ -201,18 +202,18 @@ var LwrViewRegistry = class {
|
|
|
201
202
|
view: view.id,
|
|
202
203
|
ssr: view.bootstrap?.ssr === true
|
|
203
204
|
}
|
|
204
|
-
}, () => this.renderView(view,
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
}
|
|
205
|
+
}, () => this.renderView(view, updatableViewParams, runtimeEnvironment, runtimeParams, renderOptions)));
|
|
206
|
+
viewDefinition.nonce = (0, import_utils.getViewNonce)(updatableViewParams);
|
|
207
|
+
const route = this.globalConfig.routes.find((r) => r.id === view.id);
|
|
208
|
+
const maxViewCacheTtl = (0, import_shared_utils.getFeatureFlags)().MAX_VIEW_CACHE_TTL;
|
|
209
|
+
const maxTtl = maxViewCacheTtl && parseInt(maxViewCacheTtl, 10);
|
|
210
|
+
const leastTtl = (0, import_shared_utils.shortestTtl)(viewDefinition.cache?.ttl, route?.cache?.ttl, maxTtl);
|
|
211
|
+
const ttl = leastTtl !== void 0 ? leastTtl === 0 ? 10 : leastTtl * 1e3 : void 0;
|
|
212
|
+
this.viewDefinitions.set(viewDefCacheKey, {
|
|
213
|
+
view,
|
|
214
|
+
viewDefinition,
|
|
215
|
+
paramKey: viewParamKey
|
|
216
|
+
}, {ttl});
|
|
216
217
|
return viewDefinition;
|
|
217
218
|
} catch (err) {
|
|
218
219
|
if (err instanceof import_diagnostics.DiagnosticsError) {
|
|
@@ -227,7 +228,7 @@ var LwrViewRegistry = class {
|
|
|
227
228
|
async renderView(view, viewParams, runtimeEnvironment, runtimeParams = {}, renderOptions) {
|
|
228
229
|
const {id, contentTemplate, rootComponent, layoutTemplate} = view;
|
|
229
230
|
const lwrResourcesId = `__LWR_RESOURCES__${Date.now()}`;
|
|
230
|
-
const renderedContent = await this.render({id, contentTemplate, rootComponent}, {...viewParams, lwr_resources: lwrResourcesId}, runtimeParams, renderOptions);
|
|
231
|
+
const renderedContent = await this.render({id, contentTemplate, rootComponent}, {...viewParams, lwr_resources: lwrResourcesId}, runtimeParams, runtimeEnvironment, renderOptions);
|
|
231
232
|
let normalizedRenderOptions = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderedContent.options, renderOptions);
|
|
232
233
|
const layout = layoutTemplate || renderedContent.compiledView.layoutTemplate;
|
|
233
234
|
if (!layout) {
|
|
@@ -247,7 +248,7 @@ var LwrViewRegistry = class {
|
|
|
247
248
|
...viewParams,
|
|
248
249
|
body: renderedContent.renderedView,
|
|
249
250
|
lwr_resources: lwrResourcesId
|
|
250
|
-
}, runtimeParams);
|
|
251
|
+
}, runtimeParams, runtimeEnvironment);
|
|
251
252
|
normalizedRenderOptions = (0, import_utils.normalizeRenderOptions)(this.runtimeEnvironment, renderedLayout.options, normalizedRenderOptions);
|
|
252
253
|
const renderedViewDef = await this.link({
|
|
253
254
|
...renderedLayout,
|
|
@@ -285,16 +286,16 @@ var LwrViewRegistry = class {
|
|
|
285
286
|
});
|
|
286
287
|
return renderedViewDef;
|
|
287
288
|
}
|
|
288
|
-
async render(viewId, viewParams, runtimeParams, renderOptions) {
|
|
289
|
+
async render(viewId, viewParams, runtimeParams, runtimeEnvironment, renderOptions) {
|
|
289
290
|
const globalContext = this.globalData;
|
|
290
291
|
const {id, rootComponent, contentTemplate} = viewId;
|
|
291
|
-
const compiledView = await this.getView({id, contentTemplate, rootComponent}
|
|
292
|
+
const compiledView = await this.getView({id, contentTemplate, rootComponent});
|
|
292
293
|
const result = await compiledView.render({
|
|
293
294
|
...runtimeParams,
|
|
294
295
|
...globalContext,
|
|
295
296
|
...compiledView.properties,
|
|
296
297
|
...viewParams
|
|
297
|
-
});
|
|
298
|
+
}, runtimeEnvironment);
|
|
298
299
|
const normalizedResult = (0, import_utils.normalizeRenderedResult)(result);
|
|
299
300
|
return {
|
|
300
301
|
compiledView,
|
|
@@ -360,7 +361,8 @@ var LwrViewRegistry = class {
|
|
|
360
361
|
renderedView: linkedAssetContent,
|
|
361
362
|
immutable,
|
|
362
363
|
viewRecord: {
|
|
363
|
-
assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences)
|
|
364
|
+
assetReferences: (0, import_utils.reduceSourceAssetReferences)(linkedMetadata.assetReferences),
|
|
365
|
+
moduleResources: []
|
|
364
366
|
},
|
|
365
367
|
cache: {ttl: pageTtl}
|
|
366
368
|
};
|
|
@@ -49,9 +49,8 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
49
49
|
resourceRegistry,
|
|
50
50
|
viewMetadata
|
|
51
51
|
} = resourceContext;
|
|
52
|
-
const {
|
|
52
|
+
const {format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
|
|
53
53
|
const {customElements, serverData, serverDebug} = viewMetadata;
|
|
54
|
-
const version = lwrVersion;
|
|
55
54
|
const isAMD = format === "amd";
|
|
56
55
|
const {bundleConfig} = resourceContext;
|
|
57
56
|
const {external = {}, exclude = []} = bundleConfig;
|
|
@@ -98,9 +97,12 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
98
97
|
const viewPreloads = {
|
|
99
98
|
uris: [],
|
|
100
99
|
specifiers: [],
|
|
101
|
-
groups: new Map()
|
|
100
|
+
groups: new Map(),
|
|
101
|
+
integrities: new Map()
|
|
102
102
|
};
|
|
103
103
|
const isSSR = view.bootstrap?.ssr;
|
|
104
|
+
const version = view.bootstrap?.lwrVersion;
|
|
105
|
+
const nonce = (0, import_utils.getViewNonce)(viewParams);
|
|
104
106
|
let bootstrapModuleRef, versionedSpecifier = bootstrapSpecifier;
|
|
105
107
|
const customElementsRecords = [];
|
|
106
108
|
const flattenedElements = (0, import_utils2.flattenCustomElements)(customElements, isSSR);
|
|
@@ -125,14 +127,16 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
125
127
|
if (!def.inline && !def.src) {
|
|
126
128
|
throw Error(`Invalid Shim ${shimBundle}: ${JSON.stringify(def)}`);
|
|
127
129
|
}
|
|
130
|
+
(0, import_utils.addExternalScriptNonce)(def, nonce);
|
|
128
131
|
requiredResources.push(def);
|
|
129
|
-
const errorShimDef = await resourceRegistry.getResource({specifier: "lwr-error-shim.js", version}, runtimeEnvironment, runtimeParams);
|
|
132
|
+
const errorShimDef = await resourceRegistry.getResource({specifier: "lwr-error-shim.js", version}, runtimeEnvironment, {...runtimeParams, ignoreDebug: true});
|
|
130
133
|
if (!errorShimDef) {
|
|
131
134
|
throw Error("Failed to find definition of resource: lwr-error-shim.js");
|
|
132
135
|
}
|
|
133
136
|
if (!errorShimDef.inline && !errorShimDef.src) {
|
|
134
137
|
throw Error(`Invalid Shim lwr-error-shim.js: ${JSON.stringify(errorShimDef)}`);
|
|
135
138
|
}
|
|
139
|
+
(0, import_utils.addExternalScriptNonce)(errorShimDef, nonce);
|
|
136
140
|
requiredResources.push(errorShimDef);
|
|
137
141
|
}
|
|
138
142
|
const bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
|
|
@@ -146,11 +150,13 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
146
150
|
if (!uri) {
|
|
147
151
|
throw Error(`Invalid Module Resource ${versionedSpecifier}`);
|
|
148
152
|
}
|
|
149
|
-
|
|
153
|
+
const integrity = (0, import_utils2.getBundleIntegrity)(bootstrapModuleGraph, versionedSpecifier);
|
|
154
|
+
moduleResources.push((0, import_utils.getModuleResourceByUri)(uri, runtimeEnvironment, {integrity, isPreload: false, isSSR, nonce}));
|
|
150
155
|
for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
|
|
151
156
|
const uri2 = getPreloadUri(depSpecifier, bootstrapModuleGraph.uriMap);
|
|
152
157
|
if (uri2) {
|
|
153
|
-
(0,
|
|
158
|
+
const integrity2 = (0, import_utils2.getBundleIntegrity)(bootstrapModuleGraph, depSpecifier);
|
|
159
|
+
(0, import_preload_utils.setPreloadModulesMeta)(depSpecifier, uri2, integrity2, groups, viewPreloads);
|
|
154
160
|
}
|
|
155
161
|
}
|
|
156
162
|
if ((0, import_shared_utils.isBundler)(defRegistry)) {
|
|
@@ -187,12 +193,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
187
193
|
if (!isSSR || (0, import_shared_utils.getHydrateDirective)(props)) {
|
|
188
194
|
const specifier = graph.graphs[0].specifier;
|
|
189
195
|
const uri = graph.uriMap[specifier];
|
|
190
|
-
(0,
|
|
196
|
+
const integrity = (0, import_utils2.getBundleIntegrity)(graph, specifier);
|
|
197
|
+
(0, import_preload_utils.setPreloadModulesMeta)(specifier, uri, integrity, groups, viewPreloads);
|
|
191
198
|
if (bundle) {
|
|
192
199
|
for (const depSpecifier of graph.graphs[0].static) {
|
|
193
|
-
const
|
|
194
|
-
if (
|
|
195
|
-
(0,
|
|
200
|
+
const depUri = getPreloadUri(depSpecifier, graph.uriMap);
|
|
201
|
+
if (depUri) {
|
|
202
|
+
const integrity2 = (0, import_utils2.getBundleIntegrity)(graph, depSpecifier);
|
|
203
|
+
(0, import_preload_utils.setPreloadModulesMeta)(depSpecifier, depUri, integrity2, groups, viewPreloads);
|
|
196
204
|
}
|
|
197
205
|
}
|
|
198
206
|
}
|
|
@@ -211,11 +219,19 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
211
219
|
}
|
|
212
220
|
}));
|
|
213
221
|
if (viewContainsLiveElements) {
|
|
222
|
+
if ((0, import_shared_utils.isLocalDev)()) {
|
|
223
|
+
const localDevSpecifier = "lwr_local_dev/bootstrap";
|
|
224
|
+
rootComponents.push(localDevSpecifier);
|
|
225
|
+
const localDevMod = await (0, import_utils.getModuleResource)({specifier: localDevSpecifier, version: ""}, runtimeEnvironment, {}, moduleRegistry, runtimeParams);
|
|
226
|
+
if (localDevMod.src)
|
|
227
|
+
imports[localDevSpecifier] = localDevMod.src;
|
|
228
|
+
}
|
|
214
229
|
configResources.unshift((0, import_utils2.getViewBootstrapConfigurationResource)({
|
|
215
230
|
id: view.id,
|
|
216
231
|
url: viewParams?.page?.url,
|
|
217
232
|
configAsSrc: view.bootstrap?.configAsSrc || false,
|
|
218
|
-
mixedMode: view.bootstrap?.mixedMode || false
|
|
233
|
+
mixedMode: view.bootstrap?.mixedMode || false,
|
|
234
|
+
nonce: viewParams?.page?.nonce
|
|
219
235
|
}, {
|
|
220
236
|
appId: appIdentity.appName,
|
|
221
237
|
bootstrapModule: versionedSpecifier,
|
|
@@ -235,7 +251,13 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
235
251
|
}
|
|
236
252
|
const dedupedUris = [...new Set(viewPreloads.uris)];
|
|
237
253
|
for (const preloadUri of dedupedUris) {
|
|
238
|
-
|
|
254
|
+
const integrity = viewPreloads.integrities.get(preloadUri);
|
|
255
|
+
moduleResources.push((0, import_utils.getModuleResourceByUri)(preloadUri, runtimeEnvironment, {
|
|
256
|
+
integrity,
|
|
257
|
+
isPreload: true,
|
|
258
|
+
isSSR,
|
|
259
|
+
nonce
|
|
260
|
+
}));
|
|
239
261
|
}
|
|
240
262
|
const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(import_utils.generateHtmlTag));
|
|
241
263
|
return {
|
|
@@ -243,6 +265,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
243
265
|
viewRecord: {
|
|
244
266
|
resources: requiredResources,
|
|
245
267
|
customElements: customElementsRecords,
|
|
268
|
+
moduleResources,
|
|
246
269
|
bootstrapModule: bootstrapModuleRef
|
|
247
270
|
}
|
|
248
271
|
};
|
|
@@ -29,7 +29,7 @@ __export(exports, {
|
|
|
29
29
|
});
|
|
30
30
|
var import_diagnostics = __toModule(require("@lwrjs/diagnostics"));
|
|
31
31
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
32
|
-
function setPreloadModulesMeta(specifier, uri, groups, preloads) {
|
|
32
|
+
function setPreloadModulesMeta(specifier, uri, integrity, groups, preloads) {
|
|
33
33
|
if (!uri) {
|
|
34
34
|
throw (0, import_diagnostics.createSingleDiagnosticError)({
|
|
35
35
|
description: import_diagnostics.descriptions.UNRESOLVABLE.PRELOAD_MODULE(specifier)
|
|
@@ -41,6 +41,7 @@ function setPreloadModulesMeta(specifier, uri, groups, preloads) {
|
|
|
41
41
|
const preloadModulesSpecifiers = preloads.specifiers;
|
|
42
42
|
const preloadBundleGroupsMap = preloads.groups;
|
|
43
43
|
const preloadModulesURIs = preloads.uris;
|
|
44
|
+
const preloadModuleIntegrities = preloads.integrities;
|
|
44
45
|
preloadModulesSpecifiers.push(specifier);
|
|
45
46
|
const {specifier: unversionedSpecifier} = (0, import_shared_utils.explodeSpecifier)(specifier);
|
|
46
47
|
const groupName = (0, import_shared_utils.getGroupName)(unversionedSpecifier, groups);
|
|
@@ -49,6 +50,7 @@ function setPreloadModulesMeta(specifier, uri, groups, preloads) {
|
|
|
49
50
|
}
|
|
50
51
|
preloadModulesURIs.push(uri);
|
|
51
52
|
groupName && preloadBundleGroupsMap.set(groupName, true);
|
|
53
|
+
preloadModuleIntegrities.set(uri, integrity);
|
|
52
54
|
}
|
|
53
55
|
async function getPreloadModulesMeta(specifier, viewPreloads, bundleConfig, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, pending) {
|
|
54
56
|
const {exclude = [], external = {}, groups = {}} = bundleConfig;
|
|
@@ -72,9 +74,10 @@ async function getPreloadModulesMeta(specifier, viewPreloads, bundleConfig, modu
|
|
|
72
74
|
});
|
|
73
75
|
const uri = await defRegistry.resolveModuleUri(versionedModuleId, runtimeEnvironment, runtimeParams);
|
|
74
76
|
const normalizedSpecifier = versionedModuleId.version === import_shared_utils.VERSION_NOT_PROVIDED ? specifier : versionedModuleSpecifier;
|
|
75
|
-
|
|
77
|
+
const preloadModuleRecord = await defRegistry.getModuleBundle(versionedModuleId, runtimeEnvironment, runtimeParams);
|
|
78
|
+
const {integrity} = preloadModuleRecord;
|
|
79
|
+
setPreloadModulesMeta(normalizedSpecifier, uri, integrity, groups, viewPreloads);
|
|
76
80
|
if (exclude.length || Object.keys(groups).length) {
|
|
77
|
-
const preloadModuleRecord = await defRegistry.getModuleBundle(versionedModuleId, runtimeEnvironment, runtimeParams);
|
|
78
81
|
const {imports} = preloadModuleRecord.bundleRecord;
|
|
79
82
|
if (imports) {
|
|
80
83
|
if (!pending) {
|
|
@@ -25,6 +25,7 @@ var __toModule = (module2) => {
|
|
|
25
25
|
__markAsModule(exports);
|
|
26
26
|
__export(exports, {
|
|
27
27
|
flattenCustomElements: () => flattenCustomElements,
|
|
28
|
+
getBundleIntegrity: () => getBundleIntegrity,
|
|
28
29
|
getViewBootstrapConfigurationResource: () => getViewBootstrapConfigurationResource,
|
|
29
30
|
getViewHmrConfigurationResource: () => getViewHmrConfigurationResource
|
|
30
31
|
});
|
|
@@ -72,6 +73,7 @@ function getViewBootstrapConfigurationResource(viewInfo, config, runtimeEnvironm
|
|
|
72
73
|
type: CONTENT_TYPE,
|
|
73
74
|
content: configString,
|
|
74
75
|
inline: false,
|
|
76
|
+
nonce: viewInfo.nonce,
|
|
75
77
|
src: url
|
|
76
78
|
};
|
|
77
79
|
} else {
|
|
@@ -129,3 +131,8 @@ function flattenCustomElements(arr, isSSR = false) {
|
|
|
129
131
|
flatten(arr);
|
|
130
132
|
return ret;
|
|
131
133
|
}
|
|
134
|
+
function getBundleIntegrity(bootstrapModuleGraph, versionedSpecifier) {
|
|
135
|
+
const def = bootstrapModuleGraph.linkedDefinitions[versionedSpecifier];
|
|
136
|
+
const integrity = def?.integrity;
|
|
137
|
+
return integrity;
|
|
138
|
+
}
|
|
@@ -41,10 +41,9 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
41
41
|
resourceRegistry,
|
|
42
42
|
viewMetadata
|
|
43
43
|
} = resourceContext;
|
|
44
|
-
const {
|
|
44
|
+
const {format, hmrEnabled, bundle, debug, minify} = runtimeEnvironment;
|
|
45
45
|
const {customElements, serverData, serverDebug} = viewMetadata;
|
|
46
46
|
const defRegistry = bundle ? moduleBundler : moduleRegistry;
|
|
47
|
-
const version = lwrVersion;
|
|
48
47
|
const isAMD = format === "amd";
|
|
49
48
|
const depth = isAMD ? {static: import_shared_utils.GraphDepth.ALL, dynamic: 1} : {static: import_shared_utils.GraphDepth.NONE, dynamic: 1};
|
|
50
49
|
const {bundleConfig} = resourceContext;
|
|
@@ -87,9 +86,12 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
87
86
|
const viewPreloads = {
|
|
88
87
|
uris: [],
|
|
89
88
|
specifiers: [],
|
|
90
|
-
groups: new Map()
|
|
89
|
+
groups: new Map(),
|
|
90
|
+
integrities: new Map()
|
|
91
91
|
};
|
|
92
92
|
const isSSR = view.bootstrap?.ssr;
|
|
93
|
+
const version = view.bootstrap?.lwrVersion;
|
|
94
|
+
const nonce = (0, import_utils.getViewNonce)(viewParams);
|
|
93
95
|
let bootstrapModuleRef, versionedSpecifier = bootstrapSpecifier;
|
|
94
96
|
let importMetadata = {imports: {}};
|
|
95
97
|
const customElementsRecords = [];
|
|
@@ -105,14 +107,16 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
105
107
|
if (!def.inline && !def.src) {
|
|
106
108
|
throw Error(`Invalid Shim ${shimBundle}: ${JSON.stringify(def)}`);
|
|
107
109
|
}
|
|
110
|
+
(0, import_utils.addExternalScriptNonce)(def, nonce);
|
|
108
111
|
requiredResources.push(def);
|
|
109
|
-
const errorShimDef = await resourceRegistry.getResource({specifier: "lwr-error-shim.js", version}, runtimeEnvironment, runtimeParams);
|
|
112
|
+
const errorShimDef = await resourceRegistry.getResource({specifier: "lwr-error-shim.js", version}, runtimeEnvironment, {...runtimeParams, ignoreDebug: true});
|
|
110
113
|
if (!errorShimDef) {
|
|
111
114
|
throw Error("Failed to find definition of resource: lwr-error-shim.js");
|
|
112
115
|
}
|
|
113
116
|
if (!errorShimDef.inline && !errorShimDef.src) {
|
|
114
117
|
throw Error(`Invalid Shim lwr-error-shim.js: ${JSON.stringify(errorShimDef)}`);
|
|
115
118
|
}
|
|
119
|
+
(0, import_utils.addExternalScriptNonce)(errorShimDef, nonce);
|
|
116
120
|
requiredResources.push(errorShimDef);
|
|
117
121
|
}
|
|
118
122
|
const bootstrapModuleGraph = await (0, import_shared_utils.getModuleGraphs)(bootstrapSpecifier, {includeUris: true, includeLinkedDefinitions: true, depth}, moduleRegistry, defRegistry, runtimeEnvironment, runtimeParams, visitedCache);
|
|
@@ -126,11 +130,13 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
126
130
|
if (!uri) {
|
|
127
131
|
throw Error(`Invalid Module Resource ${versionedSpecifier}`);
|
|
128
132
|
}
|
|
129
|
-
|
|
133
|
+
const integrity = (0, import_utils2.getBundleIntegrity)(bootstrapModuleGraph, versionedSpecifier);
|
|
134
|
+
moduleResources.push((0, import_utils.getModuleResourceByUri)(uri, runtimeEnvironment, {integrity, isPreload: false, isSSR, nonce}));
|
|
130
135
|
for (const depSpecifier of bootstrapModuleGraph.graphs[0].static) {
|
|
131
136
|
const uri2 = getPreloadUri(depSpecifier, bootstrapModuleGraph.uriMap);
|
|
132
137
|
if (uri2) {
|
|
133
|
-
(0,
|
|
138
|
+
const integrity2 = (0, import_utils2.getBundleIntegrity)(bootstrapModuleGraph, depSpecifier);
|
|
139
|
+
(0, import_preload_utils.setPreloadModulesMeta)(depSpecifier, uri2, integrity2, groups, viewPreloads);
|
|
134
140
|
}
|
|
135
141
|
}
|
|
136
142
|
if ((0, import_shared_utils.isBundler)(defRegistry)) {
|
|
@@ -168,12 +174,14 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
168
174
|
if (!isSSR || (0, import_shared_utils.getHydrateDirective)(props)) {
|
|
169
175
|
const specifier = graph.graphs[0].specifier;
|
|
170
176
|
const uri = graph.uriMap[specifier];
|
|
171
|
-
(0,
|
|
177
|
+
const integrity = (0, import_utils2.getBundleIntegrity)(graph, specifier);
|
|
178
|
+
(0, import_preload_utils.setPreloadModulesMeta)(specifier, uri, integrity, groups, viewPreloads);
|
|
172
179
|
if (bundle) {
|
|
173
180
|
for (const depSpecifier of graph.graphs[0].static) {
|
|
174
|
-
const
|
|
175
|
-
if (
|
|
176
|
-
(0,
|
|
181
|
+
const depUri = getPreloadUri(depSpecifier, graph.uriMap);
|
|
182
|
+
if (depUri) {
|
|
183
|
+
const integrity2 = (0, import_utils2.getBundleIntegrity)(graph, depSpecifier);
|
|
184
|
+
(0, import_preload_utils.setPreloadModulesMeta)(depSpecifier, depUri, integrity2, groups, viewPreloads);
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
187
|
}
|
|
@@ -197,7 +205,8 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
197
205
|
id: view.id,
|
|
198
206
|
url: viewParams?.page?.url,
|
|
199
207
|
configAsSrc: view.bootstrap?.configAsSrc || false,
|
|
200
|
-
mixedMode: view.bootstrap?.mixedMode || false
|
|
208
|
+
mixedMode: view.bootstrap?.mixedMode || false,
|
|
209
|
+
nonce: viewParams?.page?.nonce
|
|
201
210
|
}, {
|
|
202
211
|
appId: appIdentity.appName,
|
|
203
212
|
bootstrapModule: versionedSpecifier,
|
|
@@ -215,7 +224,13 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
215
224
|
}
|
|
216
225
|
const dedupedUris = [...new Set(viewPreloads.uris)];
|
|
217
226
|
for (const preloadUri of dedupedUris) {
|
|
218
|
-
|
|
227
|
+
const integrity = viewPreloads.integrities.get(preloadUri);
|
|
228
|
+
moduleResources.push((0, import_utils.getModuleResourceByUri)(preloadUri, runtimeEnvironment, {
|
|
229
|
+
integrity,
|
|
230
|
+
isPreload: true,
|
|
231
|
+
isSSR,
|
|
232
|
+
nonce
|
|
233
|
+
}));
|
|
219
234
|
}
|
|
220
235
|
const htmlResources = await Promise.all([...configResources, ...requiredResources, ...moduleResources].map(import_utils.generateHtmlTag));
|
|
221
236
|
const mapping = (0, import_shared_utils.getMappingUriPrefix)(runtimeEnvironment, runtimeParams);
|
|
@@ -231,6 +246,7 @@ async function getHtmlResources(view, viewParams, resourceContext) {
|
|
|
231
246
|
customElements: customElementsRecords,
|
|
232
247
|
endpoints,
|
|
233
248
|
importMetadata,
|
|
249
|
+
moduleResources,
|
|
234
250
|
bootstrapModule: bootstrapModuleRef
|
|
235
251
|
}
|
|
236
252
|
};
|
package/build/cjs/utils.cjs
CHANGED
|
@@ -24,11 +24,14 @@ var __toModule = (module2) => {
|
|
|
24
24
|
// packages/@lwrjs/view-registry/src/utils.ts
|
|
25
25
|
__markAsModule(exports);
|
|
26
26
|
__export(exports, {
|
|
27
|
+
addExternalScriptNonce: () => addExternalScriptNonce,
|
|
27
28
|
createJsonModule: () => createJsonModule,
|
|
28
29
|
generateHtmlTag: () => generateHtmlTag,
|
|
29
30
|
generatePageContext: () => generatePageContext,
|
|
31
|
+
generateViewNonce: () => generateViewNonce,
|
|
30
32
|
getModuleResource: () => getModuleResource,
|
|
31
33
|
getModuleResourceByUri: () => getModuleResourceByUri,
|
|
34
|
+
getViewNonce: () => getViewNonce,
|
|
32
35
|
isViewResponse: () => isViewResponse,
|
|
33
36
|
normalizeRenderOptions: () => normalizeRenderOptions,
|
|
34
37
|
normalizeRenderedResult: () => normalizeRenderedResult,
|
|
@@ -38,17 +41,26 @@ __export(exports, {
|
|
|
38
41
|
var import_path = __toModule(require("path"));
|
|
39
42
|
var import_shared_utils = __toModule(require("@lwrjs/shared-utils"));
|
|
40
43
|
var import_identity = __toModule(require("@lwrjs/app-service/identity"));
|
|
44
|
+
var import_crypto = __toModule(require("crypto"));
|
|
41
45
|
function generateExternalStyle(src) {
|
|
42
46
|
return `<link rel="stylesheet" href="${src}">`;
|
|
43
47
|
}
|
|
44
|
-
function generateExternalScript(type = "application/javascript", src, async, defer) {
|
|
48
|
+
function generateExternalScript(type = "application/javascript", src, async, defer, nonce, integrity) {
|
|
45
49
|
let scriptLoadOrder = "";
|
|
46
50
|
if (defer) {
|
|
47
51
|
scriptLoadOrder = " defer";
|
|
48
52
|
} else if (async) {
|
|
49
53
|
scriptLoadOrder = " async";
|
|
50
54
|
}
|
|
51
|
-
|
|
55
|
+
let cspHashAttr = "";
|
|
56
|
+
if ((0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE) {
|
|
57
|
+
if (integrity) {
|
|
58
|
+
cspHashAttr = ` integrity="${integrity}"`;
|
|
59
|
+
} else if (nonce) {
|
|
60
|
+
cspHashAttr = ` nonce="${nonce}"`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return `<script type="${type}"${scriptLoadOrder}${cspHashAttr} src="${src}"></script>`;
|
|
52
64
|
}
|
|
53
65
|
function generateLinkPreloadTag({href, type}) {
|
|
54
66
|
if (type === "module") {
|
|
@@ -57,19 +69,27 @@ function generateLinkPreloadTag({href, type}) {
|
|
|
57
69
|
return `<link rel="preload" href="${href}" type="${type}" />`;
|
|
58
70
|
}
|
|
59
71
|
}
|
|
60
|
-
function generateExternalTag({
|
|
72
|
+
function generateExternalTag({
|
|
73
|
+
type,
|
|
74
|
+
src = "",
|
|
75
|
+
async,
|
|
76
|
+
defer,
|
|
77
|
+
isPreload,
|
|
78
|
+
nonce,
|
|
79
|
+
integrity
|
|
80
|
+
}) {
|
|
61
81
|
if (isPreload) {
|
|
62
82
|
return generateLinkPreloadTag({href: src, type});
|
|
63
83
|
} else if (type === "text/css") {
|
|
64
84
|
return generateExternalStyle(src);
|
|
65
85
|
} else {
|
|
66
|
-
return generateExternalScript(type, src, async, defer);
|
|
86
|
+
return generateExternalScript(type, src, async, defer, nonce, integrity);
|
|
67
87
|
}
|
|
68
88
|
}
|
|
69
89
|
async function generateInlineTag({specifier, type, content, stream, nonce}) {
|
|
70
90
|
const typeStr = type === "text/css" ? "" : ` type="${type}"`;
|
|
71
91
|
const tag = type === "text/css" ? "style" : "script";
|
|
72
|
-
const nonceStr = nonce ? ` nonce="${nonce}"` : "";
|
|
92
|
+
const nonceStr = (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE && nonce && nonce ? ` nonce="${nonce}"` : "";
|
|
73
93
|
if (!content && !stream) {
|
|
74
94
|
throw new Error(`Invalid inline Resource Definition: must have either "content" or "stream": "${specifier}"`);
|
|
75
95
|
}
|
|
@@ -117,7 +137,6 @@ function normalizeRenderOptions(runtimeEnvironment, overrideRenderOptions, baseR
|
|
|
117
137
|
return {
|
|
118
138
|
skipMetadataCollection: false,
|
|
119
139
|
freezeAssets: runtimeEnvironment.immutableAssets,
|
|
120
|
-
skipCaching: false,
|
|
121
140
|
viewParamCacheKey: null,
|
|
122
141
|
...baseRenderOptions,
|
|
123
142
|
...overrideRenderOptions
|
|
@@ -223,14 +242,16 @@ async function getModuleResource(moduleId, runtimeEnvironment, moduleResourceMet
|
|
|
223
242
|
};
|
|
224
243
|
}
|
|
225
244
|
function getModuleResourceByUri(uri, runtimeEnvironment, moduleResourceMeta) {
|
|
226
|
-
const {isSSR = false, isPreload = false} = moduleResourceMeta;
|
|
245
|
+
const {integrity, isSSR = false, isPreload = false, nonce} = moduleResourceMeta;
|
|
227
246
|
const {format} = runtimeEnvironment;
|
|
228
247
|
return {
|
|
229
248
|
src: uri,
|
|
230
249
|
type: format === "amd" ? "application/javascript" : "module",
|
|
231
250
|
async: !isSSR && isPreload,
|
|
232
251
|
defer: isSSR,
|
|
233
|
-
isPreload: format !== "amd" && isPreload
|
|
252
|
+
isPreload: format !== "amd" && isPreload,
|
|
253
|
+
integrity,
|
|
254
|
+
nonce
|
|
234
255
|
};
|
|
235
256
|
}
|
|
236
257
|
async function createJsonModule(specifier, moduleRegistry, environment, params) {
|
|
@@ -252,3 +273,21 @@ async function createJsonModule(specifier, moduleRegistry, environment, params)
|
|
|
252
273
|
}
|
|
253
274
|
};
|
|
254
275
|
}
|
|
276
|
+
function getViewNonce(viewParams) {
|
|
277
|
+
return (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE ? viewParams?.page?.nonce : void 0;
|
|
278
|
+
}
|
|
279
|
+
function generateViewNonce(viewParams) {
|
|
280
|
+
if ((0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE) {
|
|
281
|
+
const nonce = import_crypto.default.randomBytes(16).toString("base64");
|
|
282
|
+
if (!viewParams.page) {
|
|
283
|
+
viewParams.page = {nonce};
|
|
284
|
+
} else {
|
|
285
|
+
viewParams.page.nonce = nonce;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function addExternalScriptNonce(def, nonce) {
|
|
290
|
+
if (nonce && (0, import_shared_utils.getFeatureFlags)().ENABLE_NONCE && !def.inline) {
|
|
291
|
+
def.nonce = nonce;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
@@ -130,6 +130,8 @@ var LwrViewHandler = class {
|
|
|
130
130
|
const paths = {rootDir, assets, contentDir, layoutsDir};
|
|
131
131
|
const locale = runtimeParams.locale;
|
|
132
132
|
const basePath = runtimeParams.basePath;
|
|
133
|
+
const assetBasePath = runtimeParams.assetBasePath;
|
|
134
|
+
const uiBasePath = runtimeParams.assetBasePath;
|
|
133
135
|
const viewApi = this.getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams);
|
|
134
136
|
const response = await (0, import_instrumentation.getTracer)().trace({
|
|
135
137
|
name: import_instrumentation.ViewSpan.ExecuteRouteHandler,
|
|
@@ -139,7 +141,7 @@ var LwrViewHandler = class {
|
|
|
139
141
|
}
|
|
140
142
|
}, async () => {
|
|
141
143
|
try {
|
|
142
|
-
return await routeHandlerFn({...viewRequest, locale, basePath}, {route, viewApi, ...paths}, routeHandlerOptions);
|
|
144
|
+
return await routeHandlerFn({...viewRequest, locale, basePath, assetBasePath, uiBasePath}, {route, viewApi, ...paths}, routeHandlerOptions);
|
|
143
145
|
} catch (err) {
|
|
144
146
|
if (err instanceof import_diagnostics.DiagnosticsError) {
|
|
145
147
|
throw err;
|
|
@@ -148,6 +150,9 @@ var LwrViewHandler = class {
|
|
|
148
150
|
throw (0, import_diagnostics.createSingleDiagnosticError)({description: import_diagnostics.descriptions.APPLICATION.ROUTE_HANDLER_ERROR(route.id, message)}, import_diagnostics.LwrApplicationError);
|
|
149
151
|
}
|
|
150
152
|
});
|
|
153
|
+
if (response?.locale) {
|
|
154
|
+
runtimeParams.locale = response.locale;
|
|
155
|
+
}
|
|
151
156
|
return response;
|
|
152
157
|
}
|
|
153
158
|
getBoundApi(viewRequest, route, runtimeEnvironment, runtimeParams) {
|
|
@@ -164,6 +169,9 @@ var LwrViewHandler = class {
|
|
|
164
169
|
async getViewResponse(viewRequest, route, runtimeEnvironment, runtimeParams = {}, view, viewParams, renderOptions) {
|
|
165
170
|
const {id, bootstrap} = route;
|
|
166
171
|
const managedView = {...view, id, bootstrap};
|
|
172
|
+
if (view.locale) {
|
|
173
|
+
runtimeParams.locale = view.locale;
|
|
174
|
+
}
|
|
167
175
|
const viewResponse = {
|
|
168
176
|
view: managedView,
|
|
169
177
|
viewParams,
|
package/build/es/index.d.ts
CHANGED
|
@@ -42,7 +42,7 @@ export declare class LwrViewRegistry implements ViewRegistry {
|
|
|
42
42
|
addViewTransformers(transformers: ViewTransformPlugin[]): void;
|
|
43
43
|
initializeViewProviders(): Promise<void[]>;
|
|
44
44
|
delegateGetView(viewId: ViewIdentity): Promise<CompiledView>;
|
|
45
|
-
getView(viewId: ViewIdentity
|
|
45
|
+
getView(viewId: ViewIdentity): Promise<CompiledView>;
|
|
46
46
|
hasViewDefinition(view: View, viewParams: ViewParams, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams, renderOptions?: RenderOptions): boolean;
|
|
47
47
|
getViewDefinition(view: View, viewParams: ViewParams, runtimeEnvironment: RuntimeEnvironment, runtimeParams?: RuntimeParams, renderOptions?: RenderOptions): Promise<LinkedViewDefinition>;
|
|
48
48
|
private renderView;
|