UNPKG

@applicaster/zapp-react-native-utils

Version:

Applicaster Zapp React Native utilities package

90 lines (74 loc) 2.72 kB
const R = require("ramda"); const { getDefaultConfiguration } = require("./_internals"); const indexByKey = R.indexBy((obj) => R.prop(obj.group ? "label" : "key", obj)); const propIfExist = R.curry((prop) => R.when(R.prop(prop), R.prop(prop))); const isIterable = R.or(R.is(Object), R.is(Array)); const extractFields = propIfExist("fields"); const isGroup = R.propEq("group", true); const mergeManifestWithDefaultValues = (defaultManifestValues) => (manifest) => { try { // skipping mapping if there are no default values provided if (!defaultManifestValues) { return manifest; } const merger = (left, right) => { const fields = R.ifElse( R.all(isGroup), () => mapper({ left })(right, "left"), // Map again if merging a group () => undefined )([left, right]); return R.compose( // replacing fields array with the transformed one R.when(() => fields, R.set(R.lensProp("fields"), fields)), // merging top object values R.mergeDeepRight )(left, right); }; const mapper = (defaults) => (val, key) => { if (isIterable(val)) { const defaultKeyValues = defaults?.[key]; // If current key exists in the default values if (defaultKeyValues) { /** * Transforming array to indexed object for easier merging * in => [{key: 'one'}, {key: 'two'}] * out => {one: {key: 'one'}, two: {key: 'two'}} */ const indexedDefaultValues = indexByKey( extractFields(defaultKeyValues) ); const indexedCurrentValue = indexByKey(extractFields(val)); return R.compose( R.when(() => val.fields && !isGroup(val), R.objOf("fields")), R.values, R.mergeWith(merger) )(indexedDefaultValues, indexedCurrentValue); } } return val; }; return R.compose( R.mergeRight(defaultManifestValues), R.mapObjIndexed(mapper(defaultManifestValues)) )(manifest); } catch (err) { // eslint-disable-next-line no-console console.warn( "Merging of the default values failed. Returning unmodified manifest", err ); return manifest; } }; const createConfig = (manifestFactory, options = {}) => { const { extend } = options; return (props) => { const defaultConfiguration = getDefaultConfiguration(extend, props); return R.compose( mergeManifestWithDefaultValues(defaultConfiguration), manifestFactory )(props); }; }; module.exports = { createConfig };