Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
exotic-core / dist / src / coerce / toCoerceWrap.js
Size: Mime:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const deps_1 = require("../../deps");
const array_1 = require("../../types/array");
const obj_1 = require("../../types/obj");
const properties_1 = require("../../types/attributes/properties");
const DEBUGS = [];
const DEBUG = x => DEBUGS.push(x);
// const toCoercer = x => (isFunction(x) ? x : Typed(x).coerce)
// @TODO should add check to see if IT HAS A DEFAULT first
// then check the `is`
// then use the default accordingly - at least use default when empty?
const toCoercer = x => Typed(x).coerce;
const isClassLike = Klass => obj_1.isObjWithKeys(Klass);
// possible uses
// 1. wrapping function args
// 2. wrapping NTH function arg
// 3. wrapping Class methods (static, proto)
// 4. defaulting ALL or N args, ignoring HOW MANY args are passed in
// 5. coercing & defaulting args ONLY when they are passed in
// 6. coerceIf ?
function Shape(types) {
    // curried, but better api because shape can be arguments style not array
    function wrapFunction(fn) {
        // arity(fn.length)
        // this is the actual wrapping function
        return function coersionWrapper() {
            const args = array_1.fromArgumentsToArray.apply(null, arguments);
            // console.log({args}, 'coersionWrapper')
            const evolved = args.map((arg, index) => {
                // const arg = args[index]
                const type = types[index];
                const evolver = toCoercer(type);
                // console.log({
                //   evolver,
                //   arg,
                //   typeof: typeof type,
                //   index,
                //   type,
                //   typed: Typed(type),
                // })
                const evolution = evolver(arg);
                // @NOTE defaulting
                return !evolution && type
                    ? type.empty ? type.empty(arg, index) : type
                    : evolution;
            });
            return fn.apply(this, evolved);
        };
    }
    const wrapMethods = (shape, Klass) => {
        const updateMethod = (method, methodName, index) => {
            if (properties_1.hasIn(shape, method)) {
                // DEBUG('shape has method')
                return wrapFunction(shape[method])(method);
            }
            else {
                // DEBUG('no method for shape')
                return method;
            }
        };
        return deps_1.overStaticMethods(Klass, updateMethod);
    };
    const wrapFunctionOrKlass = (shape, functionOrKlass) => {
        // DEBUG({shape, functionOrKlass})
        if (isClassLike(functionOrKlass)) {
            // DEBUG('isClassLike')
            return wrapMethods(shape, functionOrKlass);
        }
        else {
            // DEBUG('function')
            return wrapFunction(functionOrKlass);
        }
    };
    // scoped function class
    function shaper(fn) {
        return wrapFunctionOrKlass(types, fn);
    }
    shaper.types = types;
    shaper.changeByExample = shaper;
    shaper.wrap = wrapFunctionOrKlass;
    shaper.wrapMethods = wrapMethods;
    shaper.wrapFunction = wrapFunction;
    return shaper;
}
exports.Shape = Shape;
// @TODO and this will allow shaping a shema with `Typed` first too
const toShape = function () {
    return Shape(arguments.length === 1
        ? array_1.toArray(arguments[0])
        : array_1.fromArgumentsToArray.apply(this, arguments));
};
exports.toShape = toShape;
exports.default = toShape;
//# sourceMappingURL=toCoerceWrap.js.map