Comparing version 2.0.1 to 2.0.2
@@ -113,3 +113,8 @@ "use strict"; | ||
const either = yield this.run(); | ||
return helpers.liftEither(either.bimap(f, g)); | ||
try { | ||
return (yield helpers.liftEither(either.bimap(f, g))); | ||
} | ||
catch (e) { | ||
throw yield e; | ||
} | ||
})); | ||
@@ -116,0 +121,0 @@ } |
199
esm/Codec.js
@@ -1,5 +0,8 @@ | ||
import { Either, Right, Left } from './Either.js'; | ||
import { identity } from './Function.js'; | ||
import { Maybe, Just, Nothing } from './Maybe.js'; | ||
import { NonEmptyList } from './NonEmptyList.js'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseError = exports.map = exports.intersect = exports.date = exports.tuple = exports.nonEmptyList = exports.maybe = exports.lazy = exports.exactly = exports.record = exports.array = exports.oneOf = exports.enumeration = exports.unknown = exports.boolean = exports.nullable = exports.optional = exports.nullType = exports.number = exports.string = exports.Codec = void 0; | ||
const Either_js_1 = require("./Either.js"); | ||
const Function_js_1 = require("./Function.js"); | ||
const Maybe_js_1 = require("./Maybe.js"); | ||
const NonEmptyList_js_1 = require("./NonEmptyList.js"); | ||
const serializeValue = (_, value) => { | ||
@@ -69,3 +72,3 @@ return typeof value === 'bigint' ? value.toString() : value; | ||
}; | ||
export const Codec = { | ||
exports.Codec = { | ||
/** Creates a codec for any JSON object */ | ||
@@ -76,3 +79,3 @@ interface(properties) { | ||
if (!isObject(input)) { | ||
return Left(reportError('an object', input)); | ||
return (0, Either_js_1.Left)(reportError('an object', input)); | ||
} | ||
@@ -83,7 +86,7 @@ const result = {}; | ||
!properties[key]._isOptional) { | ||
return Left(`Problem with property "${key}": it does not exist in received object ${JSON.stringify(input, serializeValue)}`); | ||
return (0, Either_js_1.Left)(`Problem with property "${key}": it does not exist in received object ${JSON.stringify(input, serializeValue)}`); | ||
} | ||
const decodedProperty = properties[key].decode(input[key]); | ||
if (decodedProperty.isLeft()) { | ||
return Left(`Problem with the value of property "${key}": ${decodedProperty.extract()}`); | ||
return (0, Either_js_1.Left)(`Problem with the value of property "${key}": ${decodedProperty.extract()}`); | ||
} | ||
@@ -95,3 +98,3 @@ const value = decodedProperty.extract(); | ||
} | ||
return Right(result); | ||
return (0, Either_js_1.Right)(result); | ||
}; | ||
@@ -134,56 +137,58 @@ const encode = (input) => { | ||
/** A codec for any string value. Most of the time you will use it to implement an interface codec (see the Codec#interface example above). Encoding a string acts like the identity function */ | ||
export const string = Codec.custom({ | ||
exports.string = exports.Codec.custom({ | ||
decode: (input) => typeof input === 'string' | ||
? Right(input) | ||
: Left(reportError('a string', input)), | ||
encode: identity, | ||
? (0, Either_js_1.Right)(input) | ||
: (0, Either_js_1.Left)(reportError('a string', input)), | ||
encode: Function_js_1.identity, | ||
schema: () => ({ type: 'string' }) | ||
}); | ||
/** A codec for any number value. This includes anything that has a typeof number - NaN, Infinity etc. Encoding a number acts like the identity function */ | ||
export const number = Codec.custom({ | ||
exports.number = exports.Codec.custom({ | ||
decode: (input) => typeof input === 'number' | ||
? Right(input) | ||
: Left(reportError('a number', input)), | ||
encode: identity, | ||
? (0, Either_js_1.Right)(input) | ||
: (0, Either_js_1.Left)(reportError('a number', input)), | ||
encode: Function_js_1.identity, | ||
schema: () => ({ type: 'number' }) | ||
}); | ||
/** A codec for null only */ | ||
export const nullType = Codec.custom({ | ||
decode: (input) => input === null ? Right(input) : Left(reportError('a null', input)), | ||
encode: identity, | ||
exports.nullType = exports.Codec.custom({ | ||
decode: (input) => input === null ? (0, Either_js_1.Right)(input) : (0, Either_js_1.Left)(reportError('a null', input)), | ||
encode: Function_js_1.identity, | ||
schema: () => ({ type: 'null' }) | ||
}); | ||
const undefinedType = Codec.custom({ | ||
const undefinedType = exports.Codec.custom({ | ||
decode: (input) => input === undefined | ||
? Right(input) | ||
: Left(reportError('an undefined', input)), | ||
encode: identity | ||
? (0, Either_js_1.Right)(input) | ||
: (0, Either_js_1.Left)(reportError('an undefined', input)), | ||
encode: Function_js_1.identity | ||
}); | ||
export const optional = (codec) => ({ | ||
...oneOf([codec, undefinedType]), | ||
const optional = (codec) => ({ | ||
...(0, exports.oneOf)([codec, undefinedType]), | ||
schema: codec.schema, | ||
_isOptional: true | ||
}); | ||
exports.optional = optional; | ||
/** A codec for a value T or null. Keep in mind if you use `nullable` inside `Codec.interface` the property will still be required */ | ||
export const nullable = (codec) => oneOf([codec, nullType]); | ||
const nullable = (codec) => (0, exports.oneOf)([codec, exports.nullType]); | ||
exports.nullable = nullable; | ||
/** A codec for a boolean value */ | ||
export const boolean = Codec.custom({ | ||
exports.boolean = exports.Codec.custom({ | ||
decode: (input) => typeof input === 'boolean' | ||
? Right(input) | ||
: Left(reportError('a boolean', input)), | ||
encode: identity, | ||
? (0, Either_js_1.Right)(input) | ||
: (0, Either_js_1.Left)(reportError('a boolean', input)), | ||
encode: Function_js_1.identity, | ||
schema: () => ({ type: 'boolean' }) | ||
}); | ||
/** A codec that can never fail, but of course you get no type information. Encoding an unknown acts like the identity function */ | ||
export const unknown = Codec.custom({ | ||
decode: Right, | ||
encode: identity, | ||
exports.unknown = exports.Codec.custom({ | ||
decode: Either_js_1.Right, | ||
encode: Function_js_1.identity, | ||
schema: () => ({}) | ||
}); | ||
/** A codec for a TypeScript enum */ | ||
export const enumeration = (e) => { | ||
const enumeration = (e) => { | ||
const enumValues = Object.values(e); | ||
return Codec.custom({ | ||
return exports.Codec.custom({ | ||
decode: (input) => { | ||
return oneOf([string, number]) | ||
return (0, exports.oneOf)([exports.string, exports.number]) | ||
.decode(input) | ||
@@ -193,12 +198,13 @@ .chain((x) => { | ||
return enumIndex !== -1 | ||
? Right(enumValues[enumIndex]) | ||
: Left(reportError('an enum member', input)); | ||
? (0, Either_js_1.Right)(enumValues[enumIndex]) | ||
: (0, Either_js_1.Left)(reportError('an enum member', input)); | ||
}); | ||
}, | ||
encode: identity, | ||
encode: Function_js_1.identity, | ||
schema: () => ({ enum: enumValues }) | ||
}); | ||
}; | ||
exports.enumeration = enumeration; | ||
/** A codec combinator that receives a list of codecs and runs them one after another during decode and resolves to whichever returns Right or to Left if all fail */ | ||
export const oneOf = (codecs) => Codec.custom({ | ||
const oneOf = (codecs) => exports.Codec.custom({ | ||
decode: (input) => { | ||
@@ -215,3 +221,3 @@ let errors = []; | ||
} | ||
return Left(`One of the following problems occured: ${errors | ||
return (0, Either_js_1.Left)(`One of the following problems occured: ${errors | ||
.map((err, i) => `(${i}) ${err}`) | ||
@@ -222,3 +228,3 @@ .join(', ')}`); | ||
for (const codec of codecs) { | ||
const res = Either.encase(() => codec.encode(input)) | ||
const res = Either_js_1.Either.encase(() => codec.encode(input)) | ||
.mapLeft((_) => '') | ||
@@ -234,7 +240,8 @@ .chain(codec.decode); | ||
}); | ||
exports.oneOf = oneOf; | ||
/** A codec for an array */ | ||
export const array = (codec) => Codec.custom({ | ||
const array = (codec) => exports.Codec.custom({ | ||
decode: (input) => { | ||
if (!Array.isArray(input)) { | ||
return Left(reportError('an array', input)); | ||
return (0, Either_js_1.Left)(reportError('an array', input)); | ||
} | ||
@@ -249,6 +256,6 @@ else { | ||
else { | ||
return Left(`Problem with the value at index ${i}: ${decoded.extract()}`); | ||
return (0, Either_js_1.Left)(`Problem with the value at index ${i}: ${decoded.extract()}`); | ||
} | ||
} | ||
return Right(result); | ||
return (0, Either_js_1.Right)(result); | ||
} | ||
@@ -262,16 +269,17 @@ }, | ||
}); | ||
const numberString = Codec.custom({ | ||
decode: (input) => string | ||
exports.array = array; | ||
const numberString = exports.Codec.custom({ | ||
decode: (input) => exports.string | ||
.decode(input) | ||
.chain((x) => isFinite(+x) ? Right(x) : Left(reportError('a number', input))), | ||
encode: identity, | ||
schema: number.schema | ||
.chain((x) => isFinite(+x) ? (0, Either_js_1.Right)(x) : (0, Either_js_1.Left)(reportError('a number', input))), | ||
encode: Function_js_1.identity, | ||
schema: exports.number.schema | ||
}); | ||
/** A codec for an object without specific properties, its restrictions are equivalent to the Record<K, V> type so you can only check for number and string keys */ | ||
export const record = (keyCodec, valueCodec) => Codec.custom({ | ||
const record = (keyCodec, valueCodec) => exports.Codec.custom({ | ||
decode: (input) => { | ||
const result = {}; | ||
const keyCodecOverride = keyCodec === number ? numberString : keyCodec; | ||
const keyCodecOverride = keyCodec === exports.number ? numberString : keyCodec; | ||
if (!isObject(input)) { | ||
return Left(reportError('an object', input)); | ||
return (0, Either_js_1.Left)(reportError('an object', input)); | ||
} | ||
@@ -286,10 +294,10 @@ for (const key of Object.keys(input)) { | ||
else if (decodedKey.isLeft()) { | ||
return Left(`Problem with key type of property "${key}": ${decodedKey.extract()}`); | ||
return (0, Either_js_1.Left)(`Problem with key type of property "${key}": ${decodedKey.extract()}`); | ||
} | ||
else if (decodedValue.isLeft()) { | ||
return Left(`Problem with the value of property "${key}": ${decodedValue.extract()}`); | ||
return (0, Either_js_1.Left)(`Problem with the value of property "${key}": ${decodedValue.extract()}`); | ||
} | ||
} | ||
} | ||
return Right(result); | ||
return (0, Either_js_1.Right)(result); | ||
}, | ||
@@ -310,8 +318,9 @@ encode: (input) => { | ||
}); | ||
exports.record = record; | ||
/** A codec that only succeeds decoding when the value is exactly what you've constructed the codec with */ | ||
export const exactly = (...expectedValues) => Codec.custom({ | ||
const exactly = (...expectedValues) => exports.Codec.custom({ | ||
decode: (input) => expectedValues.includes(input) | ||
? Right(input) | ||
: Left(reportError(expectedValues.map((x) => JSON.stringify(x)).join(', '), input)), | ||
encode: identity, | ||
? (0, Either_js_1.Right)(input) | ||
: (0, Either_js_1.Left)(reportError(expectedValues.map((x) => JSON.stringify(x)).join(', '), input)), | ||
encode: Function_js_1.identity, | ||
schema: () => ({ | ||
@@ -324,4 +333,5 @@ oneOf: expectedValues.map((value) => ({ | ||
}); | ||
exports.exactly = exactly; | ||
/** A special codec used when dealing with recursive data structures, it allows a codec to be recursively defined by itself */ | ||
export const lazy = (getCodec) => Codec.custom({ | ||
const lazy = (getCodec) => exports.Codec.custom({ | ||
decode: (input) => getCodec().decode(input), | ||
@@ -333,8 +343,9 @@ encode: (input) => getCodec().encode(input), | ||
}); | ||
exports.lazy = lazy; | ||
/** A codec for purify's Maybe type. Encode runs Maybe#toJSON, which effectively returns the value inside if it's a Just or undefined if it's Nothing */ | ||
export const maybe = (codec) => { | ||
const baseCodec = Codec.custom({ | ||
decode: (input) => Maybe.fromNullable(input).caseOf({ | ||
Just: (x) => codec.decode(x).map(Just), | ||
Nothing: () => Right(Nothing) | ||
const maybe = (codec) => { | ||
const baseCodec = exports.Codec.custom({ | ||
decode: (input) => Maybe_js_1.Maybe.fromNullable(input).caseOf({ | ||
Just: (x) => codec.decode(x).map(Maybe_js_1.Just), | ||
Nothing: () => (0, Either_js_1.Right)(Maybe_js_1.Nothing) | ||
}), | ||
@@ -351,9 +362,10 @@ encode: (input) => input.map(codec.encode).orDefault(undefined), | ||
}; | ||
exports.maybe = maybe; | ||
/** A codec for purify's NEL type */ | ||
export const nonEmptyList = (codec) => { | ||
const arrayCodec = array(codec); | ||
return Codec.custom({ | ||
const nonEmptyList = (codec) => { | ||
const arrayCodec = (0, exports.array)(codec); | ||
return exports.Codec.custom({ | ||
decode: (input) => arrayCodec | ||
.decode(input) | ||
.chain((x) => NonEmptyList.fromArray(x).toEither(`Expected an array with one or more elements, but received an empty array`)), | ||
.chain((x) => NonEmptyList_js_1.NonEmptyList.fromArray(x).toEither(`Expected an array with one or more elements, but received an empty array`)), | ||
encode: arrayCodec.encode, | ||
@@ -363,10 +375,11 @@ schema: () => ({ ...arrayCodec.schema(), minItems: 1 }) | ||
}; | ||
exports.nonEmptyList = nonEmptyList; | ||
/** The same as the array decoder, but accepts a fixed amount of array elements and you can specify each element type, much like the tuple type */ | ||
export const tuple = (codecs) => Codec.custom({ | ||
const tuple = (codecs) => exports.Codec.custom({ | ||
decode: (input) => { | ||
if (!Array.isArray(input)) { | ||
return Left(reportError('an array', input)); | ||
return (0, Either_js_1.Left)(reportError('an array', input)); | ||
} | ||
else if (codecs.length !== input.length) { | ||
return Left(`Expected an array of length ${codecs.length}, but received an array with length of ${input.length}`); | ||
return (0, Either_js_1.Left)(`Expected an array of length ${codecs.length}, but received an array with length of ${input.length}`); | ||
} | ||
@@ -381,6 +394,6 @@ else { | ||
else { | ||
return Left(`Problem with the value at index ${i}: ${decoded.extract()}`); | ||
return (0, Either_js_1.Left)(`Problem with the value at index ${i}: ${decoded.extract()}`); | ||
} | ||
} | ||
return Right(result); | ||
return (0, Either_js_1.Right)(result); | ||
} | ||
@@ -397,10 +410,11 @@ }, | ||
}); | ||
exports.tuple = tuple; | ||
/** A codec for a parsable date string, on successful decoding it resolves to a Date object. The validity of the date string during decoding is decided by the browser implementation of Date.parse. Encode runs toISOString on the passed in date object */ | ||
export const date = Codec.custom({ | ||
decode: (input) => string | ||
exports.date = exports.Codec.custom({ | ||
decode: (input) => exports.string | ||
.decode(input) | ||
.mapLeft((err) => `Problem with date string: ${err}`) | ||
.chain((x) => Number.isNaN(Date.parse(x)) | ||
? Left('Expected a valid date string, but received a string that cannot be parsed') | ||
: Right(new Date(x))), | ||
? (0, Either_js_1.Left)('Expected a valid date string, but received a string that cannot be parsed') | ||
: (0, Either_js_1.Right)(new Date(x))), | ||
encode: (input) => input.toISOString(), | ||
@@ -410,3 +424,3 @@ schema: () => ({ type: 'string', format: 'date-time' }) | ||
/** Creates an intersection between two codecs. If the provided codecs are not for an object, the second decode result will be returned */ | ||
export const intersect = (t, u) => Codec.custom({ | ||
const intersect = (t, u) => exports.Codec.custom({ | ||
decode: (input) => { | ||
@@ -424,4 +438,4 @@ const et = t.decode(input); | ||
return isObject(valuet) && isObject(valueu) | ||
? Right(Object.assign(valuet, valueu)) | ||
: Right(valueu); | ||
? (0, Either_js_1.Right)(Object.assign(valuet, valueu)) | ||
: (0, Either_js_1.Right)(valueu); | ||
}, | ||
@@ -437,5 +451,6 @@ encode: (input) => { | ||
}); | ||
exports.intersect = intersect; | ||
/** A codec for the built-in Map type */ | ||
export const map = (keyCodec, valueCodec) => Codec.custom({ | ||
decode: (input) => array(tuple([keyCodec, valueCodec])) | ||
const map = (keyCodec, valueCodec) => exports.Codec.custom({ | ||
decode: (input) => (0, exports.array)((0, exports.tuple)([keyCodec, valueCodec])) | ||
.decode(input) | ||
@@ -458,2 +473,3 @@ .map((pairs) => new Map(pairs)), | ||
}); | ||
exports.map = map; | ||
const oneofRegex = /^(One of the following problems occured:)\s/; | ||
@@ -500,3 +516,3 @@ const oneOfCounterRegex = /\(\d\)\s/; | ||
/** Turns a string error message produced by a built-in purify codec into a meta object */ | ||
export const parseError = (error) => { | ||
const parseError = (error) => { | ||
const oneOfCheck = error.match(oneofRegex); | ||
@@ -510,3 +526,3 @@ // One of the following problems occured: (0) *, (1) * | ||
.split(oneOfSeparatorRegex) | ||
.map((x) => parseError(x.replace(x.match(oneOfCounterRegex)[0], ''))) | ||
.map((x) => (0, exports.parseError)(x.replace(x.match(oneOfCounterRegex)[0], ''))) | ||
}; | ||
@@ -556,3 +572,3 @@ } | ||
property: property, | ||
error: parseError(restOfError.join('')) | ||
error: (0, exports.parseError)(restOfError.join('')) | ||
}; | ||
@@ -562,3 +578,3 @@ } | ||
if (error.startsWith(dateFailureMarket)) { | ||
return parseError(error.replace(dateFailureMarket, '')); | ||
return (0, exports.parseError)(error.replace(dateFailureMarket, '')); | ||
} | ||
@@ -573,3 +589,3 @@ // Problem with the value at index 0: * | ||
index: Number(index), | ||
error: parseError(restOfError.join('')) | ||
error: (0, exports.parseError)(restOfError.join('')) | ||
}; | ||
@@ -579,1 +595,2 @@ } | ||
}; | ||
exports.parseError = parseError; |
@@ -1,3 +0,6 @@ | ||
import { Just, Nothing } from './Maybe.js'; | ||
export const Either = { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Right = exports.Left = exports.Either = void 0; | ||
const Maybe_js_1 = require("./Maybe.js"); | ||
exports.Either = { | ||
of(value) { | ||
@@ -46,3 +49,3 @@ return right(value); | ||
'fantasy-land/of'(value) { | ||
return Either.of(value); | ||
return exports.Either.of(value); | ||
} | ||
@@ -139,6 +142,6 @@ }; | ||
toMaybe() { | ||
return Just(this.__value); | ||
return (0, Maybe_js_1.Just)(this.__value); | ||
} | ||
leftToMaybe() { | ||
return Nothing; | ||
return Maybe_js_1.Nothing; | ||
} | ||
@@ -152,3 +155,3 @@ extract() { | ||
} | ||
Right.prototype.constructor = Either; | ||
Right.prototype.constructor = exports.Either; | ||
class Left { | ||
@@ -246,6 +249,6 @@ constructor(__value) { | ||
toMaybe() { | ||
return Nothing; | ||
return Maybe_js_1.Nothing; | ||
} | ||
leftToMaybe() { | ||
return Just(this.__value); | ||
return (0, Maybe_js_1.Just)(this.__value); | ||
} | ||
@@ -259,5 +262,6 @@ extract() { | ||
} | ||
Left.prototype.constructor = Either; | ||
Left.prototype.constructor = exports.Either; | ||
const left = (value) => new Left(value); | ||
exports.Left = left; | ||
const right = (value) => new Right(value); | ||
export { left as Left, right as Right }; | ||
exports.Right = right; |
@@ -0,4 +1,7 @@ | ||
"use strict"; | ||
var _a; | ||
import { Either, Left, Right } from './Either.js'; | ||
import { MaybeAsync } from './MaybeAsync.js'; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.EitherAsync = void 0; | ||
const Either_js_1 = require("./Either.js"); | ||
const MaybeAsync_js_1 = require("./MaybeAsync.js"); | ||
const helpers = { | ||
@@ -35,3 +38,3 @@ liftEither(either) { | ||
join() { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const either = await this; | ||
@@ -46,3 +49,3 @@ if (either.isRight()) { | ||
ap(eitherF) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const otherValue = await eitherF; | ||
@@ -62,3 +65,3 @@ if (otherValue.isRight()) { | ||
alt(other) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const thisValue = await this.run(); | ||
@@ -75,7 +78,7 @@ if (thisValue.isRight()) { | ||
extend(f) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const either = await this.run(); | ||
if (either.isRight()) { | ||
const v = EitherAsync.liftEither(either); | ||
return helpers.liftEither(Right(f(v))); | ||
const v = exports.EitherAsync.liftEither(either); | ||
return helpers.liftEither((0, Either_js_1.Right)(f(v))); | ||
} | ||
@@ -87,19 +90,24 @@ return helpers.liftEither(either); | ||
try { | ||
return Right(await this.runPromise(helpers)); | ||
return (0, Either_js_1.Right)(await this.runPromise(helpers)); | ||
} | ||
catch (e) { | ||
return Left(e); | ||
return (0, Either_js_1.Left)(e); | ||
} | ||
} | ||
bimap(f, g) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const either = await this.run(); | ||
return helpers.liftEither(either.bimap(f, g)); | ||
try { | ||
return (await helpers.liftEither(either.bimap(f, g))); | ||
} | ||
catch (e) { | ||
throw await e; | ||
} | ||
}); | ||
} | ||
map(f) { | ||
return EitherAsync((helpers) => this.runPromise(helpers).then(f)); | ||
return (0, exports.EitherAsync)((helpers) => this.runPromise(helpers).then(f)); | ||
} | ||
mapLeft(f) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
try { | ||
@@ -114,3 +122,3 @@ return await this.runPromise(helpers); | ||
chain(f) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const value = await this.runPromise(helpers); | ||
@@ -121,3 +129,3 @@ return helpers.fromPromise(f(value)); | ||
chainLeft(f) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
try { | ||
@@ -132,3 +140,3 @@ return await this.runPromise(helpers); | ||
toMaybeAsync() { | ||
return MaybeAsync(async ({ liftMaybe }) => { | ||
return (0, MaybeAsync_js_1.MaybeAsync)(async ({ liftMaybe }) => { | ||
const either = await this.run(); | ||
@@ -139,11 +147,11 @@ return liftMaybe(either.toMaybe()); | ||
swap() { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const either = await this.run(); | ||
if (either.isRight()) | ||
helpers.throwE(either.extract()); | ||
return helpers.liftEither(Right(either.extract())); | ||
return helpers.liftEither((0, Either_js_1.Right)(either.extract())); | ||
}); | ||
} | ||
ifLeft(effect) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const either = await this.run(); | ||
@@ -155,3 +163,3 @@ either.ifLeft(effect); | ||
ifRight(effect) { | ||
return EitherAsync(async (helpers) => { | ||
return (0, exports.EitherAsync)(async (helpers) => { | ||
const either = await this.run(); | ||
@@ -169,12 +177,12 @@ either.ifRight(effect); | ||
finally(effect) { | ||
return EitherAsync(({ fromPromise }) => fromPromise(this.run().finally(effect))); | ||
return (0, exports.EitherAsync)(({ fromPromise }) => fromPromise(this.run().finally(effect))); | ||
} | ||
} | ||
_a = Symbol.toStringTag; | ||
export const EitherAsync = Object.assign((runPromise) => new EitherAsyncImpl(runPromise), { | ||
fromPromise: (f) => EitherAsync(({ fromPromise: fP }) => fP(f())), | ||
liftEither: (either) => EitherAsync(({ liftEither }) => liftEither(either)), | ||
lefts: (list) => Promise.all(list.map((x) => x.run())).then(Either.lefts), | ||
rights: (list) => Promise.all(list.map((x) => x.run())).then(Either.rights), | ||
sequence: (eas) => EitherAsync(async (helpers) => { | ||
exports.EitherAsync = Object.assign((runPromise) => new EitherAsyncImpl(runPromise), { | ||
fromPromise: (f) => (0, exports.EitherAsync)(({ fromPromise: fP }) => fP(f())), | ||
liftEither: (either) => (0, exports.EitherAsync)(({ liftEither }) => liftEither(either)), | ||
lefts: (list) => Promise.all(list.map((x) => x.run())).then(Either_js_1.Either.lefts), | ||
rights: (list) => Promise.all(list.map((x) => x.run())).then(Either_js_1.Either.rights), | ||
sequence: (eas) => (0, exports.EitherAsync)(async (helpers) => { | ||
let res = []; | ||
@@ -187,6 +195,6 @@ for await (const e of eas) { | ||
} | ||
return helpers.liftEither(Right(res)); | ||
return helpers.liftEither((0, Either_js_1.Right)(res)); | ||
}), | ||
all: (eas) => EitherAsync.fromPromise(async () => Promise.all(eas).then(Either.sequence)) | ||
all: (eas) => exports.EitherAsync.fromPromise(async () => Promise.all(eas).then(Either_js_1.Either.sequence)) | ||
}); | ||
EitherAsyncImpl.prototype.constructor = EitherAsync; | ||
EitherAsyncImpl.prototype.constructor = exports.EitherAsync; |
@@ -0,6 +1,11 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.curry = exports.orderToNumber = exports.compare = exports.Order = exports.always = exports.identity = void 0; | ||
/** The identity function, returns the value it was given */ | ||
export const identity = (x) => x; | ||
const identity = (x) => x; | ||
exports.identity = identity; | ||
/** Returns a function that always returns the same value. Also known as `const` in other languages */ | ||
export const always = (x) => () => x; | ||
export var Order; | ||
const always = (x) => () => x; | ||
exports.always = always; | ||
var Order; | ||
(function (Order) { | ||
@@ -10,5 +15,5 @@ Order["LT"] = "LT"; | ||
Order["GT"] = "GT"; | ||
})(Order || (Order = {})); | ||
})(Order || (exports.Order = Order = {})); | ||
/** Compares two values using the default "<" and ">" operators */ | ||
export const compare = (x, y) => { | ||
const compare = (x, y) => { | ||
if (x > y) { | ||
@@ -24,4 +29,5 @@ return Order.GT; | ||
}; | ||
exports.compare = compare; | ||
/** Maps the Order enum to the values expected by the standard ECMAScript library when doing comparison (Array.prototype.sort, for example) */ | ||
export const orderToNumber = (order) => { | ||
const orderToNumber = (order) => { | ||
switch (order) { | ||
@@ -36,4 +42,5 @@ case Order.LT: | ||
}; | ||
exports.orderToNumber = orderToNumber; | ||
/** Takes a function that receives multiple arguments and returns a "curried" version of that function that can take any number of those arguments and if they are less than needed a new function that takes the rest of them will be returned */ | ||
export const curry = (fn) => function currify(...args) { | ||
const curry = (fn) => function currify(...args) { | ||
return args.length >= fn.length | ||
@@ -43,1 +50,2 @@ ? fn.apply(undefined, args) | ||
}; | ||
exports.curry = curry; |
@@ -1,9 +0,28 @@ | ||
export * from './Codec.js'; | ||
export * from './Either.js'; | ||
export * from './Function.js'; | ||
export * from './List.js'; | ||
export * from './Maybe.js'; | ||
export { MaybeAsync } from './MaybeAsync.js'; | ||
export { EitherAsync } from './EitherAsync.js'; | ||
export * from './NonEmptyList.js'; | ||
export * from './Tuple.js'; | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.EitherAsync = exports.MaybeAsync = void 0; | ||
__exportStar(require("./Codec.js"), exports); | ||
__exportStar(require("./Either.js"), exports); | ||
__exportStar(require("./Function.js"), exports); | ||
__exportStar(require("./List.js"), exports); | ||
__exportStar(require("./Maybe.js"), exports); | ||
var MaybeAsync_js_1 = require("./MaybeAsync.js"); | ||
Object.defineProperty(exports, "MaybeAsync", { enumerable: true, get: function () { return MaybeAsync_js_1.MaybeAsync; } }); | ||
var EitherAsync_js_1 = require("./EitherAsync.js"); | ||
Object.defineProperty(exports, "EitherAsync", { enumerable: true, get: function () { return EitherAsync_js_1.EitherAsync; } }); | ||
__exportStar(require("./NonEmptyList.js"), exports); | ||
__exportStar(require("./Tuple.js"), exports); |
@@ -1,14 +0,17 @@ | ||
import { Tuple } from './Tuple.js'; | ||
import { Maybe, Just, Nothing } from './Maybe.js'; | ||
import { orderToNumber } from './Function.js'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.List = void 0; | ||
const Tuple_js_1 = require("./Tuple.js"); | ||
const Maybe_js_1 = require("./Maybe.js"); | ||
const Function_js_1 = require("./Function.js"); | ||
/** Returns Just the first element of an array or Nothing if there is none. If you don't want to work with a Maybe but still keep type safety, check out `NonEmptyList` */ | ||
const head = (list) => list.length > 0 ? Just(list[0]) : Nothing; | ||
const head = (list) => list.length > 0 ? (0, Maybe_js_1.Just)(list[0]) : Maybe_js_1.Nothing; | ||
/** Returns Just the last element of an array or Nothing if there is none */ | ||
const last = (list) => list.length > 0 ? Just(list[list.length - 1]) : Nothing; | ||
const last = (list) => list.length > 0 ? (0, Maybe_js_1.Just)(list[list.length - 1]) : Maybe_js_1.Nothing; | ||
/** Returns all elements of an array except the first */ | ||
const tail = (list) => list.length > 0 ? Just(list.slice(1)) : Nothing; | ||
const tail = (list) => list.length > 0 ? (0, Maybe_js_1.Just)(list.slice(1)) : Maybe_js_1.Nothing; | ||
/** Returns all elements of an array except the last */ | ||
const init = (list) => list.length > 0 ? Just(list.slice(0, -1)) : Nothing; | ||
const init = (list) => list.length > 0 ? (0, Maybe_js_1.Just)(list.slice(0, -1)) : Maybe_js_1.Nothing; | ||
/** Returns a tuple of an array's head and tail */ | ||
const uncons = (list) => list.length > 0 ? Just(Tuple(list[0], list.slice(1))) : Nothing; | ||
const uncons = (list) => list.length > 0 ? (0, Maybe_js_1.Just)((0, Tuple_js_1.Tuple)(list[0], list.slice(1))) : Maybe_js_1.Nothing; | ||
/* Returns the sum of all numbers inside an array */ | ||
@@ -21,3 +24,3 @@ const sum = (list) => list.reduce((acc, x) => acc + x, 0); | ||
default: | ||
return Maybe.fromNullable(list.find(f)); | ||
return Maybe_js_1.Maybe.fromNullable(list.find(f)); | ||
} | ||
@@ -30,3 +33,3 @@ } | ||
default: | ||
return Maybe.fromPredicate((x) => x !== -1, list.findIndex(f)); | ||
return Maybe_js_1.Maybe.fromPredicate((x) => x !== -1, list.findIndex(f)); | ||
} | ||
@@ -39,3 +42,3 @@ } | ||
default: | ||
return list[index] === undefined ? Nothing : Just(list[index]); | ||
return list[index] === undefined ? Maybe_js_1.Nothing : (0, Maybe_js_1.Just)(list[index]); | ||
} | ||
@@ -48,6 +51,6 @@ } | ||
default: | ||
return [...list].sort((x, y) => orderToNumber(compare(x, y))); | ||
return [...list].sort((x, y) => (0, Function_js_1.orderToNumber)(compare(x, y))); | ||
} | ||
} | ||
export const List = { | ||
exports.List = { | ||
init, | ||
@@ -54,0 +57,0 @@ uncons, |
@@ -1,3 +0,6 @@ | ||
import { Left, Right } from './Either.js'; | ||
export const Maybe = { | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Nothing = exports.Just = exports.Maybe = void 0; | ||
const Either_js_1 = require("./Either.js"); | ||
exports.Maybe = { | ||
of(value) { | ||
@@ -21,3 +24,3 @@ return just(value); | ||
case 1: | ||
return (value) => Maybe.fromPredicate(pred, value); | ||
return (value) => exports.Maybe.fromPredicate(pred, value); | ||
default: | ||
@@ -30,5 +33,5 @@ return pred(value) ? just(value) : nothing; | ||
case 1: | ||
return (list) => Maybe.mapMaybe(f, list); | ||
return (list) => exports.Maybe.mapMaybe(f, list); | ||
default: | ||
return Maybe.catMaybes(list.map(f)); | ||
return exports.Maybe.catMaybes(list.map(f)); | ||
} | ||
@@ -125,3 +128,3 @@ }, | ||
chainNullable(f) { | ||
return Maybe.fromNullable(f(this.__value)); | ||
return exports.Maybe.fromNullable(f(this.__value)); | ||
} | ||
@@ -162,3 +165,3 @@ join() { | ||
toEither(_) { | ||
return Right(this.__value); | ||
return (0, Either_js_1.Right)(this.__value); | ||
} | ||
@@ -175,3 +178,3 @@ ifJust(effect) { | ||
} | ||
Just.prototype.constructor = Maybe; | ||
Just.prototype.constructor = exports.Maybe; | ||
class Nothing { | ||
@@ -258,3 +261,3 @@ constructor() { | ||
toEither(left) { | ||
return Left(left); | ||
return (0, Either_js_1.Left)(left); | ||
} | ||
@@ -271,7 +274,8 @@ ifJust(_) { | ||
} | ||
Nothing.prototype.constructor = Maybe; | ||
Nothing.prototype.constructor = exports.Maybe; | ||
/** Constructs a Just. Represents an optional value that exists */ | ||
const just = (value) => new Just(value); | ||
exports.Just = just; | ||
/** Represents a missing value, you can think of it as a smart 'null' */ | ||
const nothing = new Nothing(); | ||
export { just as Just, nothing as Nothing }; | ||
exports.Nothing = nothing; |
@@ -0,4 +1,7 @@ | ||
"use strict"; | ||
var _a; | ||
import { Maybe, Just, Nothing } from './Maybe.js'; | ||
import { EitherAsync } from './EitherAsync.js'; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MaybeAsync = void 0; | ||
const Maybe_js_1 = require("./Maybe.js"); | ||
const EitherAsync_js_1 = require("./EitherAsync.js"); | ||
const helpers = { | ||
@@ -9,3 +12,3 @@ liftMaybe(maybe) { | ||
} | ||
throw Nothing; | ||
throw Maybe_js_1.Nothing; | ||
}, | ||
@@ -28,3 +31,3 @@ fromPromise(promise) { | ||
join() { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const maybe = await this.run(); | ||
@@ -35,7 +38,7 @@ if (maybe.isJust()) { | ||
} | ||
return helpers.liftMaybe(Nothing); | ||
return helpers.liftMaybe(Maybe_js_1.Nothing); | ||
}); | ||
} | ||
ap(maybeF) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const otherValue = await maybeF; | ||
@@ -48,10 +51,10 @@ if (otherValue.isJust()) { | ||
else { | ||
return helpers.liftMaybe(Nothing); | ||
return helpers.liftMaybe(Maybe_js_1.Nothing); | ||
} | ||
} | ||
return helpers.liftMaybe(Nothing); | ||
return helpers.liftMaybe(Maybe_js_1.Nothing); | ||
}); | ||
} | ||
alt(other) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const thisValue = await this.run(); | ||
@@ -68,13 +71,13 @@ if (thisValue.isJust()) { | ||
extend(f) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const maybe = await this.run(); | ||
if (maybe.isJust()) { | ||
const v = MaybeAsync.liftMaybe(maybe); | ||
return helpers.liftMaybe(Just(f(v))); | ||
const v = exports.MaybeAsync.liftMaybe(maybe); | ||
return helpers.liftMaybe((0, Maybe_js_1.Just)(f(v))); | ||
} | ||
return helpers.liftMaybe(Nothing); | ||
return helpers.liftMaybe(Maybe_js_1.Nothing); | ||
}); | ||
} | ||
filter(pred) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const value = await this.run(); | ||
@@ -86,13 +89,13 @@ return helpers.liftMaybe(value.filter(pred)); | ||
try { | ||
return Just(await this.runPromise(helpers)); | ||
return (0, Maybe_js_1.Just)(await this.runPromise(helpers)); | ||
} | ||
catch { | ||
return Nothing; | ||
return Maybe_js_1.Nothing; | ||
} | ||
} | ||
map(f) { | ||
return MaybeAsync((helpers) => this.runPromise(helpers).then(f)); | ||
return (0, exports.MaybeAsync)((helpers) => this.runPromise(helpers).then(f)); | ||
} | ||
chain(f) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const value = await this.runPromise(helpers); | ||
@@ -103,3 +106,3 @@ return helpers.fromPromise(f(value)); | ||
toEitherAsync(error) { | ||
return EitherAsync(async ({ liftEither }) => { | ||
return (0, EitherAsync_js_1.EitherAsync)(async ({ liftEither }) => { | ||
const maybe = await this.run(); | ||
@@ -110,3 +113,3 @@ return liftEither(maybe.toEither(error)); | ||
ifJust(effect) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const maybe = await this.run(); | ||
@@ -118,3 +121,3 @@ maybe.ifJust(effect); | ||
ifNothing(effect) { | ||
return MaybeAsync(async (helpers) => { | ||
return (0, exports.MaybeAsync)(async (helpers) => { | ||
const maybe = await this.run(); | ||
@@ -132,3 +135,3 @@ maybe.ifNothing(effect); | ||
finally(effect) { | ||
return MaybeAsync(({ fromPromise }) => fromPromise(this.run().finally(effect))); | ||
return (0, exports.MaybeAsync)(({ fromPromise }) => fromPromise(this.run().finally(effect))); | ||
} | ||
@@ -140,7 +143,7 @@ then(onfulfilled, onrejected) { | ||
_a = Symbol.toStringTag; | ||
export const MaybeAsync = Object.assign((runPromise) => new MaybeAsyncImpl(runPromise), { | ||
catMaybes: (list) => Promise.all(list).then(Maybe.catMaybes), | ||
fromPromise: (f) => MaybeAsync(({ fromPromise: fP }) => fP(f())), | ||
liftMaybe: (maybe) => MaybeAsync(({ liftMaybe }) => liftMaybe(maybe)) | ||
exports.MaybeAsync = Object.assign((runPromise) => new MaybeAsyncImpl(runPromise), { | ||
catMaybes: (list) => Promise.all(list).then(Maybe_js_1.Maybe.catMaybes), | ||
fromPromise: (f) => (0, exports.MaybeAsync)(({ fromPromise: fP }) => fP(f())), | ||
liftMaybe: (maybe) => (0, exports.MaybeAsync)(({ liftMaybe }) => liftMaybe(maybe)) | ||
}); | ||
MaybeAsyncImpl.prototype.constructor = MaybeAsync; | ||
MaybeAsyncImpl.prototype.constructor = exports.MaybeAsync; |
@@ -1,7 +0,10 @@ | ||
import { Just, Nothing } from './Maybe.js'; | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.NonEmptyList = void 0; | ||
const Maybe_js_1 = require("./Maybe.js"); | ||
const NonEmptyListConstructor = (list) => list; | ||
export const NonEmptyList = Object.assign(NonEmptyListConstructor, { | ||
fromArray: (source) => NonEmptyList.isNonEmpty(source) ? Just(source) : Nothing, | ||
exports.NonEmptyList = Object.assign(NonEmptyListConstructor, { | ||
fromArray: (source) => exports.NonEmptyList.isNonEmpty(source) ? (0, Maybe_js_1.Just)(source) : Maybe_js_1.Nothing, | ||
unsafeCoerce: (source) => { | ||
if (NonEmptyList.isNonEmpty(source)) { | ||
if (exports.NonEmptyList.isNonEmpty(source)) { | ||
return source; | ||
@@ -11,3 +14,3 @@ } | ||
}, | ||
fromTuple: (source) => NonEmptyList(source.toArray()), | ||
fromTuple: (source) => (0, exports.NonEmptyList)(source.toArray()), | ||
head: (list) => list[0], | ||
@@ -14,0 +17,0 @@ last: (list) => list[list.length - 1], |
@@ -0,1 +1,4 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Tuple = void 0; | ||
class TupleImpl { | ||
@@ -37,9 +40,9 @@ constructor(first, second) { | ||
bimap(f, g) { | ||
return Tuple(f(this.first), g(this.second)); | ||
return (0, exports.Tuple)(f(this.first), g(this.second)); | ||
} | ||
mapFirst(f) { | ||
return Tuple(f(this.first), this.second); | ||
return (0, exports.Tuple)(f(this.first), this.second); | ||
} | ||
map(f) { | ||
return Tuple(this.first, f(this.second)); | ||
return (0, exports.Tuple)(this.first, f(this.second)); | ||
} | ||
@@ -53,6 +56,6 @@ reduce(reducer, initialValue) { | ||
swap() { | ||
return Tuple(this.second, this.first); | ||
return (0, exports.Tuple)(this.second, this.first); | ||
} | ||
ap(f) { | ||
return Tuple(this.first, f.snd()(this.second)); | ||
return (0, exports.Tuple)(this.first, f.snd()(this.second)); | ||
} | ||
@@ -66,5 +69,5 @@ every(pred) { | ||
} | ||
export const Tuple = Object.assign((fst, snd) => new TupleImpl(fst, snd), { | ||
exports.Tuple = Object.assign((fst, snd) => new TupleImpl(fst, snd), { | ||
fromArray: ([fst, snd]) => { | ||
return Tuple(fst, snd); | ||
return (0, exports.Tuple)(fst, snd); | ||
}, | ||
@@ -75,10 +78,10 @@ fanout: (...args) => { | ||
case 3: | ||
return Tuple(f(value), g(value)); | ||
return (0, exports.Tuple)(f(value), g(value)); | ||
case 2: | ||
return (value) => Tuple.fanout(f, g, value); | ||
return (value) => exports.Tuple.fanout(f, g, value); | ||
default: | ||
return (g) => (value) => Tuple.fanout(f, g, value); | ||
return (g) => (value) => exports.Tuple.fanout(f, g, value); | ||
} | ||
} | ||
}); | ||
TupleImpl.prototype.constructor = Tuple; | ||
TupleImpl.prototype.constructor = exports.Tuple; |
{ | ||
"name": "purify-ts", | ||
"version": "2.0.1", | ||
"version": "2.0.2", | ||
"description": "Functional programming standard library for TypeScript ", | ||
"repository": "https://github.com/gigobyte/purify.git", | ||
"author": "gigobyte <gigobest2@gmail.com>", | ||
"author": "gigobyte <s.iliev3@gmail.com>", | ||
"license": "ISC", | ||
@@ -41,13 +41,13 @@ "sideEffects": false, | ||
"devDependencies": { | ||
"@vitest/coverage-c8": "0.31.4", | ||
"@vitest/coverage-v8": "1.1.0", | ||
"ajv": "8.12.0", | ||
"ajv-formats": "2.1.1", | ||
"coveralls": "3.1.1", | ||
"prettier": "2.8.8", | ||
"typescript": "5.1.3", | ||
"vitest": "0.31.4" | ||
"prettier": "3.1.1", | ||
"typescript": "5.3.3", | ||
"vitest": "1.1.0" | ||
}, | ||
"dependencies": { | ||
"@types/json-schema": "7.0.12" | ||
"@types/json-schema": "7.0.15" | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
202663
4622
+ Added@types/json-schema@7.0.15(transitive)
- Removed@types/json-schema@7.0.12(transitive)
Updated@types/json-schema@7.0.15