@communities-webruntime/services
Version:
If you would like to run Lightning Web Runtime without the CLI, we expose some of our programmatic APIs available in Node.js. If you're looking for the CLI documentation [you can find that here](https://www.npmjs.com/package/@communities-webruntime/cli).
120 lines • 4.97 kB
JavaScript
/**
* Copyright (c) 2021, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import * as path from 'path';
import fs from 'fs';
import { createRequire } from 'module';
import { getModuleValues } from '../app-provider/app-modules.js';
import { ContextService, MetadataService } from '../index.js';
const require = createRequire(path.join(process.cwd(), './route-handler.js'));
function getInlineContent(mode, isDesignMode, locale) {
// add script for preserving original DOM APIs
let webruntimeInitContent = `<script>
~function() {
const module = {
documentCreateElement: Document.prototype.createElement,
elementSetAttribute: Element.prototype.setAttribute,
elementAttachShadow: Element.prototype.attachShadow,
elementAppendChild: Element.prototype.appendChild,
htmlElementAddEventListener: Element.prototype.addEventListener,
iframeContentDocumentGet: Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype,'contentDocument').get,
iframeContentWindowGet: Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype,'contentWindow').get,
};
Object.freeze(module);
Object.defineProperty(window, "originalDomApis", {
writable: false,
value: module
});
}();</script>`;
// inline unsupported browser IIFE
const unsupportedBrowserPath = mode === 'prod-compat'
? '@communities-webruntime/client/dist/public/assets/isBrowserSupportedByWebruntime.min.js'
: '@communities-webruntime/client/dist/public/assets/isBrowserSupportedByWebruntime.js';
const unsupportedBrowserPathSrc = fs
.readFileSync(require.resolve(unsupportedBrowserPath))
.toString();
webruntimeInitContent += `<script>${unsupportedBrowserPathSrc}</script>`;
// inline csp violation listener if in design mode
if (isDesignMode) {
const cspViolationListenerPath = mode === 'prod-compat'
? '@communities-webruntime/design/dist/public/assets/csp-violation-listener.min.js'
: '@communities-webruntime/design/dist/public/assets/csp-violation-listener.js';
const cspViolationListenerSrc = fs
.readFileSync(require.resolve(cspViolationListenerPath))
.toString();
webruntimeInitContent += `<script>${cspViolationListenerSrc}</script>`;
}
if (mode !== 'dev') {
// Use https://rfcs.lwc.dev/rfcs/lws/0000-lwr-bootstrap#customInit-hook to inline modules
const inlineModules = getModuleValues(locale);
const customInit = `<script>
globalThis.LWR = globalThis.LWR || {};
globalThis.LWR.customInit = (lwr) => {
${Object.keys(inlineModules)
.map((name) => {
const value = inlineModules[name];
return `lwr.define("${name}", [], function(){ return ${value};})`;
})
.join('\n')}
lwr.initializeApp();
};
</script>
`;
webruntimeInitContent += customInit;
}
return webruntimeInitContent;
}
function getLocale(viewRequest) {
const { defaultLocale } = ContextService.getContext();
if (!viewRequest) {
return defaultLocale;
}
const requestLocale = viewRequest?.params['lwr.locale'];
return MetadataService.getLocales()
.map((x) => x.code)
.includes(requestLocale)
? requestLocale
: defaultLocale;
}
function getPreloadModules(mode, isDesignMode) {
if (!mode.includes('compat')) {
return '';
}
const preloadModules = [];
if (isDesignMode) {
preloadModules.push('webruntimedesign/designmode');
}
return preloadModules
.map((specifier) => {
return `<script type="application/javascript" src="/1/module/amd/1/mi/${encodeURIComponent(specifier)}/s/latest/${specifier.replace('/', '_')}"></script>`;
})
.join('\n');
}
async function customRouteHandler(viewRequest) {
const { basePath, versionKey, isDesignMode } = ContextService.getContext();
const locale = getLocale(viewRequest);
const mode = process.env.MODE || '';
const partials = MetadataService.getPartials();
Object.keys(partials).forEach((p) => {
const content = partials[p];
partials[p] = content
.replace(/{\s*basePath\s*}/g, basePath)
.replace(/{\s*versionKey\s*}/g, versionKey || '');
});
partials.webruntimeInit = getInlineContent(mode, isDesignMode, locale);
partials.preloadModules = getPreloadModules(mode, isDesignMode);
partials.language = locale;
return {
view: {
layoutTemplate: '$rootDir/dist/index.html',
},
viewParams: {
...partials,
},
};
}
export default customRouteHandler;
//# sourceMappingURL=route-handler.js.map