UNPKG

@talend/react-cmf

Version:

A framework built on top of best react libraries

185 lines (176 loc) 5.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _invariant = _interopRequireDefault(require("invariant")); var _constant = _interopRequireDefault(require("./constant")); var _registry = _interopRequireDefault(require("./registry")); var _useContext = require("./useContext"); var _lodash = require("lodash"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const regexExpression = new RegExp('(.*)Expression'); /** * @typedef {Object} Context * @property {string} store * @property {string} registry */ /** * This module define expression which are just function * used to be called in the way you want in your APP with a context and a payload as params * @module react-cmf/lib/expression */ /** * register an expression * @param {string} id the id of the expression to call it later * @param {function} func the function you want to register under this id * @param {Context} context React context is optional */ function register(id, func, context) { _registry.default.addToRegistry(`${_constant.default.REGISTRY_EXPRESSION_PREFIX}:${id}`, func, context); } /** * get an expression from it's id * @param {string} id of the expression you want to get * @param {Context} context React context is optional */ function get(id, context) { return _registry.default.getFromRegistry(`${_constant.default.REGISTRY_EXPRESSION_PREFIX}:${id}`, context); } /** * expressions are registred function which can be called through configuration * @param {string|object} expression to call * @param {object} React context * @param {object} payload will be in expression argument */ function call(expression, context, payload) { let id; let args; if (typeof expression === 'object') { id = expression.id; args = expression.args; } else if (typeof expression === 'string') { id = expression; args = []; } if (!id) { (0, _invariant.default)(process.env.NODE_ENV === 'production', 'you must provide an expression id'); } const check = get(id, context); if (!check) { (0, _invariant.default)(process.env.NODE_ENV === 'production', `you must register expression ${id} first`); } return check({ context, payload }, ...args); } /** * this function will try to find all props.properties that should be evaluated agains * a registered function, the attrs parameter will be deprecated. * Each parameter name ending with Expression will be automaticaly evaluated * against their registered Expression and the result put inside a properties with name * matching the original expression attributes minus the 'Expression' part * * @param {Object.<string, *>} props React props * @param {Array.<string>} attrs of attribute to get * @param {Context} context React context * @param {payload} payload optional payload to pass * @deprecated the array param will be deprecated and replaced with context * @deprecated the context will be replaced by the payload */ function getProps(props, attrs, context, payload = {}) { const newProps = { ...props, ...payload }; attrs.forEach(attr => { const value = props[attr]; if (typeof value === 'string' || typeof value === 'object') { // eslint-disable-next-line console.warn(`beware this is present just for the sake of backward compatibility, you should use properties ending with Expression to see them evaluated example: instead of using ${attr}, ${attr}Expression will be evaluated and result put in ${attr}`); newProps[attr] = call(value, context, newProps); } }); (0, _lodash.forIn)(props, (value, key) => { const match = regexExpression.exec(key); if (match) { newProps[match[1]] = call(props[match[0]], context, newProps); delete newProps[match[0]]; } }); return newProps; } /** * Internal: you should not have to use it * This function will compute a new props object with extra props * using the convention `fooExpression` will return { foo }; * @param {object} state redux state * @param {object} ownProps any props you want to process with expression */ function mapStateToProps(state, ownProps, ctx = {}) { const props = {}; const context = { store: { getState: () => state }, registry: _registry.default.getRegistry(), ...ctx }; (0, _lodash.forIn)(ownProps, (value, key) => { const match = regexExpression.exec(key); if (match) { props[match[1]] = call(ownProps[match[0]], context, ownProps); } }); return props; } /** * Internal: you should not have to use it * this function cleanup the object by returning a new one by removing * all key that finish with Expression (ie `fooExpression`); * @param {object} props any props object */ function mergeProps(props) { const newProps = { ...props }; (0, _lodash.forIn)(newProps, (value, key) => { const match = regexExpression.exec(key); if (match) { delete newProps[match[0]]; } }); return newProps; } /** * * @param {any} Component * @param {*} attrs */ function withExpression(Component, attrs) { function WithExpression(props) { const context = (0, _useContext.useCMFContext)(); return /*#__PURE__*/(0, _jsxRuntime.jsx)(Component, { ...getProps(props, attrs, context) }); } WithExpression.displayName = `WithExpression(${Component.displayName || Component.name})`; return WithExpression; } const registerMany = _registry.default.getRegisterMany(register); var _default = exports.default = { register, registerMany, get, call, getProps, withExpression, mapStateToProps, mergeProps }; //# sourceMappingURL=expression.js.map