@openshift-console/dynamic-plugin-sdk-webpack
Version:
Provides webpack ConsoleRemotePlugin used to build all dynamic plugin assets.
112 lines (111 loc) • 4.65 kB
JavaScript
/* 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;
;