io-ts-extra
Version:
Adds pattern matching, optional properties, and several other helpers and types, to io-ts.
70 lines • 3.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parser = exports.mapper = void 0;
const t = __importStar(require("io-ts"));
const util_1 = require("./util");
const Either = __importStar(require("fp-ts/lib/Either"));
const pipeable_1 = require("fp-ts/lib/pipeable");
/**
* A helper for building "parser-decoder" types - that is, types that validate an input,
* transform it into another type, and then validate the target type.
*
* @example
* const StringsFromMixedArray = mapper(
* t.array(t.any),
* t.array(t.string),
* mixedArray => mixedArray.filter(value => typeof value === 'string')
* )
* StringsFromMixedArray.decode(['a', 1, 'b', 2]) // right(['a', 'b'])
* StringsFromMixedArray.decode('not an array') // left(...)
*
* @see parser
*
* @param from the expected type of input value
* @param to the expected type of the decoded value
* @param map transform (decode) a `from` type to a `to` type
* @param unmap transfrom a `to` type back to a `from` type
*/
const mapper = (from, to, map, unmap = util_1.RichError.thrower('unmapper/encoder not implemented')) => {
const fail = (s, c, info) => t.failure(s, c.concat([{ key: `decoder [${util_1.funcLabel(map)}]: ${info}`, type: to }]));
const piped = from.pipe(new t.Type(to.name, to.is, (s, c) => pipeable_1.pipe(Either.tryCatch(() => map(s), err => `error thrown decoding: [${err}]`), Either.fold(e => fail(s, c, e), value => to.validate(value, c))), unmap), `${from.name} |> ${util_1.funcLabel(map)} |> ${to.name}`);
return Object.assign(piped, { from, to });
};
exports.mapper = mapper;
/**
* A helper for parsing strings into other types. A wrapper around `mapper` where the `from` type is `t.string`.
* @see mapper
*
* @example
* const IntFromString = parser(t.Int, parseFloat)
* IntFromString.decode('123') // right(123)
* IntFromString.decode('123.4') // left(...)
* IntFromString.decode('not a number') // left(...)
* IntFromString.decode(123) // left(...)
*
* @param type the target type
* @param decode transform a string into the target type
* @param encode transform the target type back into a string
*/
const parser = (type, decode, encode = String) => exports.mapper(t.string, type, decode, encode);
exports.parser = parser;
//# sourceMappingURL=mapper.js.map