UNPKG

@unsplash/sum-types-io-ts

Version:
85 lines (84 loc) 7.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getInternallyTaggedCodec = exports.getUntaggedCodec = exports.getAdjacentlyTaggedCodec = exports.getExternallyTaggedCodec = exports.getCodecFromNullaryTag = exports.getCodecFromPrimitiveMappedNullaryTag = exports.MappedType = exports.getCodecFromMappedNullaryTag = exports.getCodec = exports.getCodecFromSerialized = exports.getSerializedCodec = exports.nullaryFromEmpty = exports.nullaryFrom = void 0; const Sum = require("@unsplash/sum-types"); const function_1 = require("fp-ts/function"); const t = require("io-ts"); const A = require("fp-ts/Array"); const O = require("fp-ts/Option"); const E = require("fp-ts/Either"); const Map = require("fp-ts/Map"); const R = require("fp-ts/Record"); const Str = require("fp-ts/string"); const Tuple_1 = require("fp-ts/Tuple"); const Eq_1 = require("fp-ts/Eq"); const unknownSerialize = (x) => { return O.tryCatch(() => Sum.serialize(x)); }; const unsafeGetTags = Object.keys; const union1 = (xs, name = "union1") => xs[1] === undefined ? new t.UnionType(name, xs[0].is, xs[0].validate, xs[0].encode, xs) : t.union(xs, name); const foldToUnion = (f) => (cs, name = "Sum union") => (0, function_1.pipe)(cs, Object.entries, A.map(([k, v]) => f([k, v])), ([x, ...ys]) => union1([x, ...ys], name)); const nullaryFrom = (to) => (from) => new t.Type(`nullaryFrom(${from.name})`, t.null.is, (i, c) => (0, function_1.pipe)(from.validate(i, c), E.map((0, function_1.constant)(null))), (0, function_1.constant)(to)); exports.nullaryFrom = nullaryFrom; exports.nullaryFromEmpty = (0, exports.nullaryFrom)(undefined)(t.union([t.undefined, t.null, t.type({})])); const getSerializedCodec = () => (cs, name = "Serialized Sum") => foldToUnion((0, function_1.flow)((0, Tuple_1.mapFst)(t.literal), xs => t.tuple(xs)))(cs, name); exports.getSerializedCodec = getSerializedCodec; const getCodecFromSerialized = (sum) => (cs, name = "Sum") => { const sc = (0, exports.getSerializedCodec)()(cs, name); return new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(sc.is)), (0, function_1.flow)(sc.validate, E.map(Sum.deserialize(sum))), (0, function_1.flow)(Sum.serialize, sc.encode)); }; exports.getCodecFromSerialized = getCodecFromSerialized; const getCodec = (sum) => (cs, name = "Sum") => { const sc = (0, exports.getSerializedCodec)()(cs, name); return new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(sc.is)), (i, c) => (0, function_1.pipe)(i, unknownSerialize, O.matchW(() => t.failure(i, c), E.right), E.chain(sc.decode), E.map(Sum.deserialize(sum))), (0, function_1.flow)(Sum.serialize, sc.encode, Sum.deserialize(sum))); }; exports.getCodec = getCodec; const getCodecFromMappedNullaryTag = (sum) => (from, to) => (tags, name = "Sum Mapped Tag") => { const isKnownTag = (x) => tags.includes(x); return new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(y => isKnownTag(y[0]) && y[1] === null)), (x, ctx) => (0, function_1.pipe)(x, from, O.match(() => t.failure(x, ctx), k => t.success(Sum.deserialize(sum)([k, null])))), (0, function_1.flow)(Sum.serialize, x => x[0], to)); }; exports.getCodecFromMappedNullaryTag = getCodecFromMappedNullaryTag; class MappedType extends t.Type { Map; _tag = "@unsplash/sum-types-io-ts/MappedType"; constructor(name, is, validate, encode, Map) { super(name, is, validate, encode); this.Map = Map; } } exports.MappedType = MappedType; const getCodecFromPrimitiveMappedNullaryTag = (sum) => (tos, name = "Sum Primitive Mapped Tag") => { const froms = (0, function_1.pipe)(tos, R.reduceWithIndex(Str.Ord)(new globalThis.Map(), (k, xs, v) => Map.upsertAt(Eq_1.eqStrict)(v, k)(xs))); const codec = (0, exports.getCodecFromMappedNullaryTag)(sum)(x => Map.lookup(Eq_1.eqStrict)(x)(froms), x => tos[x])(unsafeGetTags(tos), name); return new MappedType(codec.name, codec.is, codec.validate, codec.encode, tos); }; exports.getCodecFromPrimitiveMappedNullaryTag = getCodecFromPrimitiveMappedNullaryTag; const getCodecFromNullaryTag = (sum) => (tags, name = "Sum Tag") => (0, exports.getCodecFromPrimitiveMappedNullaryTag)(sum)((0, function_1.pipe)(tags, A.reduce({}, (xs, y) => R.upsertAt(y, y)(xs))), name); exports.getCodecFromNullaryTag = getCodecFromNullaryTag; const getExternallyTaggedMemberCodec = (sum) => (k) => (vc, name = "Sum") => new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(y => y[0] === k && vc.is(y[1]))), (i, ctx) => (0, function_1.pipe)(typeof i === "object" && i !== null && k in i ? E.right(i) : t.failure(i, ctx, `Missing key "${k}"`), E.chain(x => t.strict({ [k]: vc }).validate(x, ctx)), E.map(x => Sum.deserialize(sum)([k, x[k]]))), (0, function_1.flow)(Sum.serialize, ([k, v]) => ({ [k]: vc.encode(v) }))); const getExternallyTaggedCodec = (sum) => (cs, name = "Sum") => foldToUnion(([tag, codec]) => getExternallyTaggedMemberCodec(sum)(tag)(codec, name))(cs, name); exports.getExternallyTaggedCodec = getExternallyTaggedCodec; const getAdjacentlyTaggedMemberCodec = (tagKey) => (valueKey) => (sum) => (tag) => (vc, name = "Sum") => new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(y => y[0] === tag && vc.is(y[1]))), (i, ctx) => (0, function_1.pipe)(t .strict({ [tagKey]: t.literal(tag), [valueKey]: vc }) .validate(i, ctx), E.map(x => Sum.deserialize(sum)([ tag, x[valueKey], ]))), (0, function_1.flow)(Sum.serialize, ([k, v]) => ({ [tagKey]: k, [valueKey]: vc.encode(v), }))); const getAdjacentlyTaggedCodec = (tagKey) => (valueKey) => (sum) => (cs, name = "Sum") => foldToUnion(([tag, codec]) => getAdjacentlyTaggedMemberCodec(tagKey)(valueKey)(sum)(tag)(codec, name))(cs, name); exports.getAdjacentlyTaggedCodec = getAdjacentlyTaggedCodec; const getUntaggedMemberCodec = (sum) => (k) => (c, name = "Sum") => new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(y => y[0] === k && c.is(y[1]))), (i, ctx) => (0, function_1.pipe)(c.validate(i, ctx), E.map(v => Sum.deserialize(sum)([k, v]))), (0, function_1.flow)(Sum.serialize, x => x[1], c.encode)); const getUntaggedCodec = (sum) => (cs, name = "Sum") => foldToUnion(([tag, codec]) => getUntaggedMemberCodec(sum)(tag)(codec, name))(cs, name); exports.getUntaggedCodec = getUntaggedCodec; const getInternallyTaggedMemberCodec = (tagKey) => (sum) => (tag) => (vc, name = "Sum") => new t.Type(name, (x) => (0, function_1.pipe)(unknownSerialize(x), O.exists(y => y[0] === tag && vc.is(y[1]))), (i, ctx) => (0, function_1.pipe)(t.type({ [tagKey]: t.literal(tag) }).validate(i, ctx), E.chain(x => vc.validate(x, ctx)), E.map(x => Sum.deserialize(sum)([tag, x]))), (0, function_1.flow)(Sum.serialize, ([k, v]) => ({ [tagKey]: k, ...vc.encode(v), }))); const getInternallyTaggedCodec = (tagKey) => (sum) => (cs, name = "Sum") => foldToUnion(([tag, codec]) => getInternallyTaggedMemberCodec(tagKey)(sum)(tag)(codec, name))(cs, name); exports.getInternallyTaggedCodec = getInternallyTaggedCodec;