UNPKG

@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).

232 lines 7.99 kB
"use strict"; /** * Copyright (c) 2019, 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 */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MetadataService = void 0; const crypto_1 = __importDefault(require("crypto")); const fs_1 = require("fs"); const path_1 = require("path"); const uuid_parse_1 = require("uuid-parse"); const context_service_1 = require("../context/context-service"); const files_1 = require("../utils/files"); const tree_1 = require("../utils/tree"); const assert_1 = require("../utils/assert"); const metadata_validation_1 = require("./metadata-validation"); const process_branding_1 = require("./process-branding"); const { getContext } = context_service_1.ContextService; /** * Get all the context template routes */ function getRoutes() { const { routes } = getContext(); if (typeof routes === 'object') { return routes; } return files_1.readJsonFile(routes); } /** * Get the context template theme */ function getTheme() { const { theme } = getContext(); if (typeof theme === 'object') { return theme; } return files_1.readJsonFile(theme); } /** * Get all the context template labels */ function getLabels() { const { labels } = getContext(); if (typeof labels === 'object') { return labels; } return (labels && files_1.readJsonFile(labels)) || {}; } /** * Get all the context template locales */ function getLocales() { const { locales } = getContext(); if (typeof locales === 'object') { return locales; } return locales && fs_1.existsSync(locales) ? files_1.readJsonFile(locales) : []; } /** * Get all the context template branding properties */ function getBrandingProperties() { const { theme: themeConfig } = getContext(); let brandingProperties; const theme = getTheme(); if (typeof themeConfig === 'object') { brandingProperties = (theme && theme.branding) || []; } else { const dir = path_1.dirname(themeConfig); brandingProperties = (theme && theme.branding && files_1.readJsonFile(`${dir}/${theme.branding}`)) || []; } return brandingProperties; } function getBrandingTokenMap() { return process_branding_1.getBrandingTokenMap(getBrandingProperties()); } /** * Compute components and regions uuids for design mode. * * Ids are a hash of the concatenation of the view name * and the cmp/region (deep) string representation. * * The resulting 128 bits hash is unparsed as a UUID. * * The view is mutated in place. * * @param {object} view the view to add uuids to * @returns {object} the mutated view */ function updateViewWithUuids(view) { // compute a uuid for a given region or component function uuid(node) { return uuid_parse_1.unparse(crypto_1.default .createHash('md5') .update(`${view.devName}:${JSON.stringify(node, (key, value) => { // filter out uuid and region properties cause they would impact the hash return ['uuid', 'region'].includes(key) ? undefined : value; })}`) .digest()); } // update a region recursively function updateRegionWithUuids(region) { // First, generate region key region.uuid = region.key ? region.key : uuid(region); if (region.components) { region.components.forEach((cmp) => { cmp.region = region.slotName; if (cmp.regions) { // recursively generate keys for each inner component region cmp.regions.forEach(updateRegionWithUuids); } // generate a key for the component itself cmp.uuid = uuid(cmp); }); } } // if the view has a corresponding component and this component has inner regions, generate // keys for each region if (view.component && view.component.regions) { view.component.regions.forEach(updateRegionWithUuids); } return view; } function getView(devName) { const { views, isDesignMode } = getContext(); const view = typeof views === 'object' ? views[devName] : files_1.readJsonFile(`${views}/${devName}.json`); assert_1.assert(view, `Cannot find view '${devName}'`); // Compute components and regions ids for design mode. // Ids are a hash of the concatenation of the view name // and the cmp/region (deep) string representation if (isDesignMode) { return updateViewWithUuids(view); } return view; } function getAllViews(routes = getRoutes(), theme = getTheme()) { // using `[].concat(routes)` allows the caller to pass either a single route (the current route for example) // or an array of routes const routesArr = [].concat(routes || []); // get all route views const routeViewDevNames = routesArr.filter((route) => route.view).map((route) => route.view); const routeViews = routeViewDevNames.map(getView); // get all the theme layout views const themeLayoutViewDevNames = routeViews .filter((view) => view.themeLayoutType) .map((view) => view.themeLayoutType) .filter((themeLayoutType) => { return theme.themeLayouts[themeLayoutType] && theme.themeLayouts[themeLayoutType].view; }) .map((themeLayoutType) => theme.themeLayouts[themeLayoutType].view); // filter out unique views const allUniqueViewIds = [...new Set(routeViewDevNames.concat(themeLayoutViewDevNames))]; return allUniqueViewIds.map(getView); } /** * Get all the HTML partials from the template's partials folder. * Result is in format of `{[fileNameWithoutExtension] : stringContentOfFile }` */ function getPartials() { const extension = '.html'; const { partials } = getContext(); if (typeof partials === 'object') { return partials; } const fileMap = files_1.readFolder(partials, extension); return Object.keys(fileMap).reduce((result, key) => { result[key.slice(0, -extension.length)] = fileMap[key]; return result; }, {}); } /** * Get all views which are routed */ function getViewToThemeLayoutMap() { const viewToThemeLayoutMap = {}; const theme = getTheme(); getRoutes().forEach((route) => { const view = getView(route.view); const themeLayout = theme.themeLayouts[view.themeLayoutType]; viewToThemeLayoutMap[route.view] = themeLayout.view; }); return viewToThemeLayoutMap; } function validate(schema = 'communities') { return metadata_validation_1.validate({ routes: getRoutes(), labels: getLabels(), locales: getLocales(), brandingProperties: getBrandingProperties(), theme: getTheme(), views: getAllViews(), partials: getPartials(), }, schema); } /** * Returns the component with the given UUID among all the views. * * This is only available in design mode. * * @param uuid the UUID of the component to find * @returns the component, or `undefined` if the component cannot be found * @throws an error is not in design mode */ function getComponent(uuid) { const { isDesignMode } = getContext(); assert_1.assert(isDesignMode, 'Can only get components by UUIDs in design mode'); return getAllViews().reduce((c, view) => { return c || tree_1.findInTree(view, (cmp) => cmp && cmp.uuid === uuid); }, undefined); } exports.MetadataService = { getRoutes, getTheme, getBrandingProperties, getBrandingTokenMap, getComponent, getLabels, getLocales, getView, getViewToThemeLayoutMap, getAllViews, getPartials, validate, }; //# sourceMappingURL=metadata-service.js.map