shapey
Version:
A simple syntax for remapping objects, inspired by several of Ramda's spec based functions
112 lines (100 loc) • 5.6 kB
JavaScript
;
exports.__esModule = true;
exports.impliedRemove = exports.removeAndShape = exports.remover = exports.keepAndShape = exports.keeper = void 0;
var _curry = _interopRequireDefault(require("vanillas/curry"));
var _pipe = _interopRequireDefault(require("vanillas/pipe"));
var _curried = require("vanillas/curried");
var _evolveSpec = _interopRequireDefault(require("./evolveSpec"));
var _util = require("./util");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Keeps only the props you name in your spec.
* It is expected (best practice, for conveying intent) that you give a value of `true` for props that you want to keep
* but _not_ transform (a zipped object - where key and value are both strings of the same name - makes sense too).
*
* @function
* @name keeper
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} spec An object whose values are `true` or match the key name to signal a value to be preserved (as-is) on the output
* @param {Object} input An object which will be passed through the pruning defined by the spec
* @returns {Object} The input object with the unnamed props shaved off the output
*/
var keeper = (0, _curry.default)(function (spec, input) {
return (0, _pipe.default)(_util.objectify, (0, _pipe.default)(_util.makePruningSpec, Object.keys, _curried.pick)(spec))(input);
});
/**
* Keeps only the props you name in your spec. If you provided a function, it is applied at the prop-level.
* It is expected (best practice, for conveying intent) that you give a value of `true` for props that you want to keep
* but _not_ transform (a zipped object - where key and value are both strings of the same name - makes sense too).
* In this mode, if you provide any other type of value it won't be used in the spec.
* If the prop _doesn't_ exist, you won't see it on the output
* (use shapeSuperStrictly if you want to see `undefined` for those cases instead).
*
* @function
* @name keepAndShape
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} spec An object whose values are either transform functions or (preferrably) a value of `true` to signal a value to be preserved (as-is) on the output
* @param {Object} input An object which will be passed through the pruning/re-shaping defined by the spec
* @returns {Object} The input object with the spec transforms applied to it and unnamed props shaved off the output
*/
exports.keeper = keeper;
var keepAndShape = (0, _curry.default)(function (spec, input) {
return (0, _pipe.default)(keeper(spec), (0, _evolveSpec.default)((0, _curried.filter)(function (v) {
return typeof v === 'function';
}, spec)))(input);
});
/**
* Removes the props you name in your spec.
* It is expected (best practice, for conveying intent) that you give a value of `true` for props that you want to remove
* but _not_ transform (a zipped object - where key and value are both strings of the same name - makes sense too).
*
* @function
* @name remover
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} spec An object whose values are `true` or match the key name to signal a value to be removed from the output
* @param {Object} input An object which will be passed through the pruning defined by the spec
* @returns {Object} The input object with the named props shaved off the output
*/
exports.keepAndShape = keepAndShape;
var remover = (0, _curry.default)(function (spec, input) {
return (0, _pipe.default)(_util.objectify, (0, _pipe.default)(_util.makePruningSpec, (0, _curried.filter)(function (v) {
return typeof v !== 'function';
}), Object.keys, _curried.omit)(spec))(input);
});
/**
* Removes all the props you name in your spec. If you provided a transform function however,
* it is applied at the prop-level and that prop is (obviously) NOT removed but rather transformed accordingly.
* It is expected (best practice, for conveying intent) that you give a value of `true` for props you want to remove
* (a zipped object - where key and value are both strings of the same name - makes sense too).
* In this mode, if you provide any other type of value it won't be used in the spec.
*
* @function
* @name removeAndShape
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} spec An object whose values are either transform functions or (preferrably) a value of `true` to signal a value to be remove from the output
* @param {Object} input An object which will be passed through the pruning/re-shaping defined by the spec
* @returns {Object} The input object with the spec transforms applied to it and name props shaved off the output
*/
exports.remover = remover;
var removeAndShape = (0, _curry.default)(function (spec, input) {
return (0, _pipe.default)(remover(spec), (0, _evolveSpec.default)((0, _curried.filter)(function (v) {
return typeof v === 'function';
}, spec)))(input);
});
/**
* Removes the any props from the input not named in the spec. Doesn't matter
* what the value types are in the spec: if the key name doesn't exist in the
* spec, it won't exist in the output.
*
* @function
* @name impliedRemove
* @sig {k: v} -> {k: v} -> {k: v}
* @param {Object} spec An object
* @param {Object} input An object which will have any props not named in the spect removed
* @returns {Object} The input object with the props removed which were not in the spec too
*/
exports.removeAndShape = removeAndShape;
var impliedRemove = (0, _curry.default)(function (spec, input) {
return (0, _curried.pick)(Object.keys(spec), input);
});
exports.impliedRemove = impliedRemove;