@applicaster/zapp-react-native-utils
Version:
Applicaster Zapp React Native utilities package
90 lines (74 loc) • 2.72 kB
JavaScript
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 };