Repository URL to install this package:
Version:
1.2.14 ▾
|
"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