UNPKG

@openshift-console/dynamic-plugin-sdk-webpack

Version:

Provides webpack ConsoleRemotePlugin used to build all dynamic plugin assets.

112 lines (111 loc) 4.65 kB
"use strict"; /* eslint-disable no-console */ Object.defineProperty(exports, "__esModule", { value: true }); exports.resolveExtension = exports.resolveEncodedCodeRefs = exports.loadReferencedObject = exports.parseEncodedCodeRefValue = exports.setCodeRefError = exports.getCodeRefError = exports.isCodeRefError = exports.isExecutableCodeRef = exports.isEncodedCodeRef = exports.applyCodeRefSymbol = void 0; const _ = require("lodash"); const object_1 = require("../utils/object"); const promise_1 = require("../utils/promise"); const codeRefSymbol = Symbol('CodeRef'); const applyCodeRefSymbol = (ref) => { ref[codeRefSymbol] = true; return ref; }; exports.applyCodeRefSymbol = applyCodeRefSymbol; const isEncodedCodeRef = (obj) => _.isPlainObject(obj) && _.isEqual(Object.getOwnPropertyNames(obj), ['$codeRef']) && typeof obj.$codeRef === 'string'; exports.isEncodedCodeRef = isEncodedCodeRef; const isExecutableCodeRef = (obj) => _.isFunction(obj) && _.isEqual(Object.getOwnPropertySymbols(obj), [codeRefSymbol]) && obj[codeRefSymbol] === true; exports.isExecutableCodeRef = isExecutableCodeRef; const codeRefErrorSymbol = Symbol('error'); const isCodeRefError = (ref) => !!ref[codeRefErrorSymbol]; exports.isCodeRefError = isCodeRefError; const getCodeRefError = (ref) => ref[codeRefErrorSymbol]; exports.getCodeRefError = getCodeRefError; const setCodeRefError = (ref, e) => { ref[codeRefErrorSymbol] = e; return ref; }; exports.setCodeRefError = setCodeRefError; /** * Parse the `EncodedCodeRef` value into `[moduleName, exportName]` tuple. * * Returns an empty array if the value doesn't match the expected format. */ const parseEncodedCodeRefValue = (value) => { const match = value.match(/^([^.]+)(?:\.(.+)){0,1}$/); return match ? [match[1], match[2] || 'default'] : []; }; exports.parseEncodedCodeRefValue = parseEncodedCodeRefValue; /** * Returns the object referenced by the `EncodedCodeRef`. * * If an error occurs, calls `errorCallback` and returns `null`. * * _Does not throw errors by design._ */ const loadReferencedObject = async (ref, entryModule, pluginID, errorCallback) => { const [moduleName, exportName] = (0, exports.parseEncodedCodeRefValue)(ref.$codeRef); let requestedModule; if (!moduleName) { console.error(`Malformed code reference '${ref.$codeRef}' of plugin ${pluginID}`); errorCallback(); return null; } try { const moduleFactory = await entryModule.get(moduleName); requestedModule = moduleFactory(); } catch (error) { console.error(`Failed to load module '${moduleName}' of plugin ${pluginID}`, error); errorCallback(); return null; } if (!requestedModule[exportName]) { console.error(`Missing module export '${moduleName}.${exportName}' of plugin ${pluginID}`); errorCallback(); return null; } return requestedModule[exportName]; }; exports.loadReferencedObject = loadReferencedObject; /** * Returns new `extensions` array, resolving `EncodedCodeRef` values into `CodeRef` functions. * * _Does not execute `CodeRef` functions to load the referenced objects._ */ const resolveEncodedCodeRefs = (extensions, entryModule, pluginID, errorCallback) => _.cloneDeep(extensions).map((e) => { (0, object_1.deepForOwn)(e.properties, exports.isEncodedCodeRef, (ref, key, obj) => { const loader = (0, exports.applyCodeRefSymbol)(async () => (0, exports.loadReferencedObject)(ref, entryModule, pluginID, errorCallback)); obj[key] = Object.defineProperty(loader, 'name', { value: `${pluginID}-${ref.$codeRef}` }); }); return e; }); exports.resolveEncodedCodeRefs = resolveEncodedCodeRefs; /** * Returns an extension with its `CodeRef` properties replaced with referenced objects. */ const resolveExtension = async (extension) => { const valueResolutions = []; (0, object_1.deepForOwn)(extension.properties, exports.isExecutableCodeRef, (ref, key, obj) => { if ((0, exports.isCodeRefError)(ref)) { throw (0, exports.getCodeRefError)(ref); } valueResolutions.push(ref() .then((resolvedValue) => { obj[key] = resolvedValue; if (_.isNil(resolvedValue)) { console.warn(`Code reference property '${key}' resolved to null or undefined`); } }) .catch((e) => { (0, exports.setCodeRefError)(ref, e ?? true); return e; })); }); await (0, promise_1.settleAllPromises)(valueResolutions); return extension; }; exports.resolveExtension = resolveExtension;