@thisisagile/easy
Version:
Straightforward library for building domain-driven microservice architectures
315 lines (310 loc) • 8.68 kB
JavaScript
import {
isValidatable
} from "./chunk-OFGI5FLG.mjs";
import {
isResults,
toResults
} from "./chunk-NCEWAKOZ.mjs";
import {
toResult
} from "./chunk-Q3WMGUO2.mjs";
import {
reject,
resolve
} from "./chunk-5HENJTR6.mjs";
import {
Exception
} from "./chunk-FKZ4MOTX.mjs";
import {
isValue
} from "./chunk-WSBULPUZ.mjs";
import {
isEnum
} from "./chunk-JVDKV5HE.mjs";
import {
meta
} from "./chunk-WTFW6DLP.mjs";
import {
text
} from "./chunk-MCCIBDEH.mjs";
import {
toList
} from "./chunk-A7C3XND3.mjs";
import {
toArray
} from "./chunk-CO2AFYVD.mjs";
import {
asString
} from "./chunk-BDA5LB4S.mjs";
import {
ofGet
} from "./chunk-SJGQU3OG.mjs";
import {
ofConstruct,
toName
} from "./chunk-ZPNFXK7Y.mjs";
import {
isArray,
isDefined,
isEmpty,
isFunction,
isIn,
isTrue
} from "./chunk-DEJ7A5PY.mjs";
// src/types/Try.ts
var Try = class _Try {
is = {
defined: (prop) => this.filter((v) => isDefined(prop ? prop(v) : v)),
empty: (prop) => this.filter((v) => isEmpty(prop ? prop(v) : v)),
valid: (prop) => this.filter((v) => validate(prop ? prop(v) : v).isValid),
true: (prop) => this.filter((v) => isTrue(prop ? prop(v) : v)),
false: (prop) => this.filter((v) => !isTrue(prop ? prop(v) : v)),
not: {
defined: (prop) => this.filter((v) => !isDefined(prop ? prop(v) : v)),
empty: (prop) => this.filter((v) => !isEmpty(prop ? prop(v) : v)),
valid: (prop) => this.filter((v) => !validate(prop ? prop(v) : v).isValid)
}
};
if = this.is;
static of = (c, ...args) => {
try {
const out = ofGet(c, ...args);
return new Success(out instanceof _Try ? out.value : out);
} catch (e) {
return new Failure(e);
}
};
};
var Success = class extends Try {
constructor(value) {
super();
this.value = value;
}
get error() {
throw new Error("No error found");
}
get isValid() {
return true;
}
map(f) {
return tryTo(f, this.value);
}
recover(f) {
return this;
}
recoverFrom(type, f) {
return this;
}
accept(f) {
return tryTo(() => {
f(this.value);
return this;
});
}
filter(predicate) {
return tryTo(() => {
if (predicate(this.value))
return this;
throw new Error(`Applying filter(${predicate.toString()}) failed.`);
});
}
or(value) {
return this.value;
}
orElse(value) {
return this.value;
}
orThrow(_error) {
return this.value;
}
};
var Failure = class _Failure extends Try {
constructor(error) {
super();
this.error = error;
}
get value() {
throw this.error;
}
get isValid() {
return false;
}
map(f) {
return new _Failure(this.error);
}
recover(f) {
return tryTo(f, this.error);
}
recoverFrom(type, f) {
return tryTo(() => this.error instanceof type ? this.recover(f) : this);
}
accept(f) {
return this;
}
filter(predicate) {
return this;
}
or(value) {
return ofGet(value);
}
orElse(value) {
return ofGet(value);
}
orThrow(error) {
throw ofConstruct(error);
}
};
var tryTo = (c, ...args) => Try.of(c, ...args);
// src/types/Case.ts
var CaseBuilder = class {
constructor(v) {
this.v = v;
}
case(pred, out) {
return new Case(this.v).case(pred, out);
}
type(guard, out) {
return new Case(this.v).type(guard, out);
}
equals(value, out) {
return new Case(this.v).equals(value, out);
}
is = {
defined: (prop, out) => new Case(this.v).case(isDefined(prop(this.v)), out),
empty: (prop, out) => new Case(this.v).case(isEmpty(prop(this.v)), out),
valid: (prop, out) => new Case(this.v).case(validate(prop(this.v)).isValid, out),
not: {
defined: (prop, out) => new Case(this.v).case(!isDefined(prop(this.v)), out),
empty: (prop, out) => new Case(this.v).case(!isEmpty(prop(this.v)), out),
valid: (prop, out) => new Case(this.v).case(!validate(prop(this.v)).isValid, out)
}
};
if = this.is;
};
var Case = class _Case {
constructor(value, outcome) {
this.value = value;
this.outcome = outcome;
}
case(pred, out) {
return tryTo(pred, this.value).is.true().map(() => ofGet(out, this.value)).map((res) => new Found(this.value, res)).or(this);
}
type(guard, out) {
return tryTo(guard, this.value).is.true().map(() => out(this.value)).map((res) => new Found(this.value, res)).or(this);
}
equals(value, out) {
return this.case(this.value === value, out);
}
is = {
defined: (prop, out) => new _Case(this.value).case(isDefined(prop(this.value)), out),
empty: (prop, out) => new _Case(this.value).case(isEmpty(prop(this.value)), out),
valid: (prop, out) => new _Case(this.value).case(validate(prop(this.value)).isValid, out),
not: {
defined: (prop, out) => new _Case(this.value).case(!isDefined(prop(this.value)), out),
empty: (prop, out) => new _Case(this.value).case(!isEmpty(prop(this.value)), out),
valid: (prop, out) => new _Case(this.value).case(!validate(prop(this.value)).isValid, out)
}
};
if = this.is;
else(alt) {
return ofGet(alt, this.value);
}
};
var Found = class extends Case {
constructor(value, outcome) {
super(value, outcome);
this.value = value;
this.outcome = outcome;
}
case(pred, out) {
return this;
}
type(guard, out) {
return this;
}
equals(value, out) {
return this;
}
is = {
defined: (_prop, _out) => this,
empty: (_prop, _out) => this,
valid: (_prop, _out) => this,
not: {
defined: (_prop, _out) => this,
empty: (_prop, _out) => this,
valid: (_prop, _out) => this
}
};
if = this.is;
else(alt) {
return this.outcome;
}
};
var choose = (value) => new CaseBuilder(value);
// src/validation/Validate.ts
var asResults = (subject, template, options = {}) => toResults(toResult(text(template).parse(subject, options), toName(subject)));
var validators = (subject) => meta(subject).keys("constraint").reduce((list, vs) => list.add(vs), toList());
var runValidator = (v, subject) => {
try {
const actual = isFunction(subject[v.property]) ? subject[v.property]() : subject[v.property];
const constraint = v.constraint(actual);
return isResults(constraint) ? constraint : !constraint ? asResults(subject, v.text, { ...v, actual }) : toResults();
} catch (e) {
return asResults(subject, asString(e));
}
};
var constraints = (subject) => validators(subject).map((vs) => runValidator(vs, subject)).reduce((rs, r) => rs.add(...r.results), toResults());
var validate = (subject) => choose(subject).is.not.defined(
(s) => s,
() => toResults("Subject is not defined.")
).type(isEnum, (e) => e.isValid ? toResults() : asResults(e, "This is not a valid {type}.")).type(isValue, (v) => v.isValid ? toResults() : asResults(v, "This is not a valid {type}.")).type(isArray, (a) => a.map((i) => validate(i)).reduce((rs, r) => rs.add(...r.results), toResults())).type(isValidatable, (v) => constraints(v)).else(toResults());
var validateReject = (subject) => when(subject).not.isValid.reject();
var isValid = (t) => validate(t).isValid;
// src/validation/When.ts
var When = class _When {
constructor(subject, valid = true, results) {
this.subject = subject;
this.valid = valid;
this.results = results;
}
get not() {
return this.clone(!this.valid);
}
get and() {
return this.clone(this.valid);
}
get isDefined() {
return this.clone(this.valid === isDefined(this.subject));
}
get isEmpty() {
return this.clone(this.valid === isEmpty(this.subject));
}
get isTrue() {
return this.clone(this.valid === !!this.subject);
}
get isValid() {
this.results = validate(this.subject);
return this.clone(this.valid === this.results.isValid);
}
isInstance = (c) => this.clone(this.valid === this.subject instanceof c);
with = (pred) => this.clone(this.valid === ofGet(pred, this.subject));
contains = (property) => this.clone(this.valid === isDefined(ofGet(property, this.subject)));
in = (...items) => this.clone(this.valid === isIn(this.subject, toArray(...items)));
is = (item) => this.clone(this.valid === (this.subject === item));
reject = (error) => !this.valid ? resolve(this.subject) : reject(ofGet(error, this.subject) ?? this.results ?? Exception.Unknown);
recover = (f) => resolve(!this.valid ? this.subject : f(this.subject));
clone = (result = true) => new _When(this.subject, result, this.results);
};
var when = (subject) => new When(subject);
export {
When,
when,
Try,
tryTo,
choose,
asResults,
validate,
validateReject,
isValid
};
//# sourceMappingURL=chunk-XAIHCZT4.mjs.map