UNPKG

@thisisagile/easy

Version:

Straightforward library for building domain-driven microservice architectures

1,045 lines (1,027 loc) 31.9 kB
import { isValidatable } from "./chunk-EBIF6AMC.mjs"; import { toArray } from "./chunk-KCY4RPFR.mjs"; import { traverse } from "./chunk-SSROJBD5.mjs"; import { isValue } from "./chunk-S3NSPQ7M.mjs"; import { asString, capitalize, equals, replaceAll } from "./chunk-NNA77YYC.mjs"; import { ofGet, ofProperty } from "./chunk-SJGQU3OG.mjs"; import { isA, isAn } from "./chunk-D5IYAIMK.mjs"; import { ofConstruct, on, toName, use } from "./chunk-PF7HDF6B.mjs"; import { isArray, isDefined, isEmpty, isFunction, isIn, isNotEmpty, isObject, isPresent, isTrue } from "./chunk-AAND4MKF.mjs"; // src/types/Object.ts function entries(subject) { return ifDefined( subject, () => toList([...Object.entries(subject), ...Object.entries(Object.getPrototypeOf(subject) ?? {})]), () => toList() ); } function values(subject) { return toList([...Object.values(subject), ...Object.values(Object.getPrototypeOf(subject) ?? {})]); } function keys(subject) { return toList([...Object.keys(subject), ...Object.keys(Object.getPrototypeOf(subject) ?? {})]); } function extractKeys(obj, keys2) { return keys2.filter((k) => k in obj).reduce( (acc, key) => { acc.keys[key] = obj[key]; delete acc[key]; return acc; }, { keys: {}, ...obj } ); } // src/utils/Promise.ts var resolve = (subject) => Promise.resolve(subject); var reject = (e) => Promise.reject(e); var tuple = { 2: (first, second) => Promise.all([first, second]), 3: (first, second, third) => Promise.all([first, second, third]), 4: (first, second, third, forth) => Promise.all([first, second, third, forth]), 5: (first, second, third, forth, fifth) => Promise.all([first, second, third, forth, fifth]), all: (first, second) => Promise.all([first, Promise.all(second)]), spread: (first, ...second) => Promise.all([first, Promise.all(toArray(second))]), list: (list) => Promise.all([...list]).then(toList), settled: (list) => Promise.allSettled([...list]).then((rs) => ({ fulfilled: toList(...rs.filter((r) => r.status === "fulfilled").map((r) => r.value)), rejected: toList(...rs.filter((r) => r.status === "rejected").map((r) => asString(r.reason))) })), object: (obj) => use(keys(obj), (ks) => tuple.list(values(obj)).then((vs) => vs.reduce((acc, v, i) => on(acc, (a) => a[ks[i]] = v), {}))) }; var tuple2 = tuple[2]; var tuple3 = tuple[3]; var tuple4 = tuple[4]; var tuple5 = tuple[5]; var tupleO = tuple.object; var settled = tuple.settled; // src/types/Meta.ts import "reflect-metadata"; var ClassMeta = class { constructor(subject, data = (subject.prototype ?? subject).constructor) { this.subject = subject; this.data = data; } get = (key) => Reflect.getMetadata(key, this.data); set = (key, value) => { Reflect.defineMetadata(key, value, this.data); return value; }; entries = () => entries(this.subject); parse = (f, options = {}) => { const { initial = {}, skipUndefined = false } = options; return this.entries().reduce((a, [k, val]) => use(f(val), (v) => isDefined(v) || !skipUndefined ? on(a, (a2) => a2[k] = v) : a), initial); }; properties = (key) => toList([...Object.getOwnPropertyNames(this.subject), ...Object.getOwnPropertyNames(Object.getPrototypeOf(this.subject))]).map((p) => this.property(p)).filter((p) => key ? p.get(key) : p); keys = (key) => this.properties().map((p) => p.get(key)).reduce((list, u) => u ? list.add(u) : list, toList()); values = () => values(this.subject); property = (property) => new PropertyMeta(this.subject, property); }; var PropertyMeta = class { constructor(subject, property, data = Reflect.getMetadata(property, subject)) { this.subject = subject; this.property = property; this.data = data; } get value() { return this.subject[this.property]; } get = (key) => isDefined(this.data) && isDefined(this.data[key]) ? this.data[key] : void 0; set = (key, value) => { Reflect.defineMetadata(this.property, { ...this.data, [key]: value }, this.subject); return value; }; }; var meta = (subject) => new ClassMeta(subject ?? {}); // src/types/Enum.ts var isEnumConstructor = (c) => isFunction(c) && c.isEnum; var Enum = class { constructor(name, id = name.toLowerCase(), code = id.toString()) { this.name = name; this.id = id; this.code = code; } static isEnum = true; get isValid() { return isDefined(this.id); } static all() { return meta(this.allTuple()).values(); } static filter(p, params) { return this.all().filter(p, params); } static first(p, params) { return this.all().first(p, params); } static byIds(ids = []) { return toList(ids).mapDefined((id) => this.byId(id)).distinct(); } static byId(id, alt) { return this.allTuple()[id] ?? ofGet(alt); } static allTuple() { return meta(this).get(`all-${this.name}`) ?? meta(this).set(`all-${this.name}`, meta(this).values().filter(isEnum).toObject("id")); } equals(other) { return this.id === (isEnum(other) ? other.id : other); } isIn(...items) { return items.some((i) => this.equals(i)); } toJSON() { return this.id; } toString() { return this.id.toString(); } }; var isEnum = (e) => isDefined(e) && e instanceof Enum && isAn(e, "name", "id", "code"); // 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/Template.ts var Template = class { constructor(template2, subject = {}, options = {}) { this.template = template2; this.subject = subject; this.options = options; } knownPrefixes = /* @__PURE__ */ new Set(["typeof", "property", "actual", "subject"]); toString = () => { return entries(this.options).reduce((t, [k]) => this.option(t, k), this.object()).replace(" ", " "); }; props = (tmpl, key, result = toList()) => { const i1 = tmpl.indexOf(`{${key}`); if (i1 < 0) { return result; } const i2 = tmpl.indexOf("}", i1); return this.props(tmpl.slice(i2 + 1), key, result.add(tmpl.substring(i1 + 1, i2))); }; object = () => tryTo(() => this.template.replace(/\{this\./g, "{")).map((t) => t.replace(/\{([^{}]+)}/g, (match, p) => this.knownPrefixes.has(p.split(".")[0]) ? match : textValue(this.subject, p))).or(""); option = (tmpl, prop) => { return this.props(tmpl, prop).reduce((t, p) => t.replace(`{${p}}`, textValue(this.options, p)), tmpl); }; }; function template(tmpl, subject, options = {}) { return new Template(asString(tmpl), subject, { typeof: toName(subject), subject: text(JSON.stringify(subject)), ...options }); } // src/types/ToText.ts var ToText = class { constructor(subject) { this.subject = subject; } get cap() { return this.map((s) => capitalize(s?.toLowerCase())); } get capFirst() { return this.map((s) => capitalize(s)); } get title() { return this.map( (s) => s.split(" ").map((w) => text(w).cap).join(" ") ); } get pascal() { return this.title.replace(" ", ""); } get lower() { return this.map((s) => s.toLowerCase()); } get upper() { return this.map((s) => s.toUpperCase()); } get camel() { return this.title.trim.map((s) => `${s.charAt(0).toLowerCase()}${s.slice(1)}`); } get kebab() { return this.lower.replace(" ", "-"); } get strictKebab() { return this.map((s) => s.replace(/[^a-z\d]+/gi, " ").trim()).kebab; } get slug() { return this.map( (s) => s.replace(/ß/g, "ss").normalize("NFKD").replace(/[\u0300-\u036F]/g, "").toLowerCase().replace(/[^a-z\d]+/g, "-").replace(/(^-)|(-$)/g, "") ); } get snake() { return this.upper.replace(" ", "_"); } get plural() { return this.ifLike("") ?? this.add("s"); } get space() { return this.map((s) => s.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ")); } get sentence() { return this.isEmpty ? this : this.map((s) => `${s.charAt(0).toUpperCase()}${s.slice(1)}.`); } get initials() { return this.map( (s) => s.split(" ").map((w) => w[0]).join("") ); } get trim() { return this.map((s) => s.replace(/[- ,_#]/g, "")); } get trimSentence() { return this.map( (s) => s.replace(/[\u200B-\u200D\uFEFF]/g, "").replace(/[\s\u00A0]+/g, " ").replace(/\s+([.,;:!?])/g, "$1").trim() ); } get isEmpty() { return isEmpty(this.toString()); } parse = (subject, options = {}) => text(template(this.subject, subject, { typeof: toName(subject), ...options })); is = (...others) => others.some((o) => this.toString() === text(o).toString()); equals = this.is; like = (...others) => others.some((o) => this.trim.lower.toString().includes(text(o).trim.lower.toString())); isLike = (...others) => others.some((o) => this.trim.lower.is(text(o).trim.lower)); ifLike = (...others) => this.isLike(...others) ? this : void 0; endsWith = (end) => this.subject.endsWith(asString(end)); startsWith = (end) => this.subject.startsWith(asString(end)); first = (n) => this.map((s) => s.substring(0, n)); last = (n) => this.map((s) => s.substring(s.length - n)); map = (func) => text(ofGet(func, this.subject)); replace = (search, replace) => this.map((s) => replaceAll(s, search, replace)); add = (add, separator = "") => this.map((s) => isNotEmpty(add) ? `${s}${separator}${text(add)}` : s); with = (separator, ...other) => this.map( (s) => toList(s).add(...other.map((u) => text(u).toString())).filter((s2) => isNotEmpty(s2)).join(separator) ); split = (separator = " ") => toList(this.subject.split(separator)); toString() { return this.subject; } toJSON() { return this.subject; } }; function text(subject, alt = "") { const sub = subject ? asString(subject) : alt; return new ToText(sub !== "[object Object]" ? sub : ""); } function textValue(subject, prop) { const p = prop.split("."); const root = subject?.[p[0]]; const initial = typeof root === "object" && root !== null ? root : text(root); return p.splice(1).reduce((t, s) => (typeof t === "object" && t !== null ? t : text(t))?.[s], initial)?.toString() ?? ""; } // src/types/Exception.ts var Exception = class _Exception extends Enum { constructor(message, id, reason) { super(message, id ?? text(message).pascal.toString()); this.message = message; this.reason = reason; } static AlreadyExists = new _Exception("Subject already exists"); static DoesNotExist = new _Exception("Does not exist"); static IsMissingId = new _Exception("Subject is missing an id"); static IsNotImplemented = new _Exception("Is not implemented"); static IsNotValid = new _Exception("Is not valid"); static Unknown = new _Exception("Unknown error"); static CouldNotExecute = (target) => new _Exception(`Could not execute ${target}.`, "CouldNotExecute"); static CouldNotValidate = (target) => new _Exception(`Could not validate ${target}.`, "CouldNotValidate"); static EnvironmentVariableNotFound = (variable) => new _Exception(`Environment variable ${text(variable).upper} could not be found.`, "EnvironmentVariableNotFound"); because = (reason) => new _Exception(this.message, this.id, reason); }; var isException = (e, t) => e instanceof Exception && (isDefined(t) ? e.equals(asString(t)) : true); var isDoesNotExist = (e) => e instanceof Exception && Exception.DoesNotExist.equals(e); // 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); // src/types/Context.ts var DotEnvContext = class { domain = process.env.DOMAIN ?? "easy"; name = process.env.ENVIRONMENT_NAME ?? ""; host = process.env.HOST ?? ""; port = Number.parseInt(process.env.PORT ?? "8080"); app = process.env.APP ?? ""; get = (key, alt) => { const k = text(key).map((k2) => k2.replace(/([a-z])([A-Z])/g, "$1 $2")).snake.toString(); return process.env[k] ?? alt; }; }; var BaseRequestContext = class { state = {}; get token() { return this.get("token"); } set token(token) { this.set("token", token); } get identity() { return this.token; } get jwt() { return this.get("jwt"); } set jwt(jwt) { this.set("jwt", jwt); } get correlationId() { return this.get("correlationId"); } set correlationId(id) { this.set("correlationId", id); } get lastError() { return this.get("lastError"); } set lastError(error) { this.set("lastError", error); } get(key) { return this.state[key]; } set(key, value) { return this.state[key] = value; } create = (f) => f(); wrap = (f) => f(); }; var BaseContext = class extends BaseRequestContext { }; var Context = class { constructor(state = {}) { this.state = state; this.state = { ...{ env: new DotEnvContext(), request: new BaseRequestContext(), other: {} }, ...this.state }; } get env() { return this.state.env; } set env(env) { this.state.env = env; } get request() { return this.state.request; } set request(request) { this.state.request = request; } get other() { return this.state.other; } }; var ctx = new Context(); // src/types/Result.ts var toResult = (message, location, domain = ctx.env.domain) => ({ message: message.toString(), location: location?.toString(), domain: domain?.toString() }); var isResult = (r) => isA(r, "message"); // src/types/Results.ts var parse = (...rs) => toArray(...rs).map((r) => isResult(r) ? r : toResult(r)); var Results = class { results; constructor(...rs) { this.results = parse(...rs); } get length() { return this.results.length; } get isValid() { return this.results.length === 0; } add = (...rs) => toResults(...this.results, ...parse(...rs)); }; var toResults = (...r) => new Results(...r); var isResults = (r) => isDefined(r) && r instanceof Results; // src/validation/Validate.ts var asResults = (subject, template2, options = {}) => toResults(toResult(text(template2).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 {typeof}.")).type(isValue, (v) => v.isValid ? toResults() : asResults(v, "This is not a valid {typeof}.")).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/types/Case.ts var CaseBuilder = class { constructor(v) { this.v = v; } is = { true: (pred, out) => this.case(pred, out), false: (pred, out) => this.case(!ofGet(pred, this.v), out), truthy: (prop, out) => this.case(!!prop(this.v), out), falsy: (prop, out) => this.case(!prop(this.v), out), defined: (prop, out) => this.case(isDefined(prop(this.v)), out), empty: (prop, out) => this.case(isEmpty(prop(this.v)), out), valid: (prop, out) => this.case(validate(prop(this.v)).isValid, out), in: (prop, out) => this.case(ofGet(prop, this.v).includes(this.v), out), type: (guard, out) => this.type(guard, out), not: { true: (pred, out) => this.case(!ofGet(pred, this.v), out), false: (pred, out) => this.case(pred, out), truthy: (prop, out) => this.case(!prop(this.v), out), falsy: (prop, out) => this.case(!!prop(this.v), out), defined: (prop, out) => this.case(!isDefined(prop(this.v)), out), empty: (prop, out) => this.case(!isEmpty(prop(this.v)), out), valid: (prop, out) => this.case(!validate(prop(this.v)).isValid, out), in: (prop, out) => this.case(!ofGet(prop, this.v).includes(this.v), out), type: (guard, out) => this.case((v) => !guard(v), out) } }; if = this.is; 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); } }; var Case = class { constructor(value, outcome) { this.value = value; this.outcome = outcome; } is = { true: (pred, out) => this.case(pred, out), false: (pred, out) => this.case(!ofGet(pred, this.value), out), truthy: (prop, out) => this.case(!!prop(this.value), out), falsy: (prop, out) => this.case(!prop(this.value), out), defined: (prop, out) => this.case(isDefined(prop(this.value)), out), empty: (prop, out) => this.case(isEmpty(prop(this.value)), out), valid: (prop, out) => this.case(validate(prop(this.value)).isValid, out), in: (prop, out) => this.case(ofGet(prop, this.value).includes(this.value), out), type: (guard, out) => this.type(guard, out), not: { true: (pred, out) => this.case(!ofGet(pred, this.value), out), false: (pred, out) => this.case(pred, out), truthy: (prop, out) => this.case(!prop(this.value), out), falsy: (prop, out) => this.case(!!prop(this.value), out), defined: (prop, out) => this.case(!isDefined(prop(this.value)), out), empty: (prop, out) => this.case(!isEmpty(prop(this.value)), out), valid: (prop, out) => this.case(!validate(prop(this.value)).isValid, out), in: (prop, out) => this.case(!ofGet(prop, this.value).includes(this.value), out), type: (guard, out) => this.case((v) => !guard(v), out) } }; if = this.is; 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); } 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; } else(alt) { return this.outcome; } }; var choose = (value) => new CaseBuilder(value); // src/types/IsEqual.ts var isEqualArray = (one, another) => choose([one, another]).case(([o, a]) => !isArray(o) || !isArray(a), false).case(([o, a]) => o?.length !== a?.length, false).else(([o, a]) => !o.some((v, i) => !isEqual(v, a[i]))); var isEqualObject = (one, another) => choose([Object.keys(one), Object.keys(another)]).case(([keysO, keysA]) => keysO.length !== keysA.length, false).case(([keysO, keysA]) => keysO.some((k) => !keysA.includes(k)), false).case(([keysO]) => keysO.some((k) => !isEqual(one[k], another[k])), false).else(true); var isEqual = (one, another) => choose([one, another]).case(([o, a]) => o === a, true).case( ([o, a]) => isArray(o) || isArray(a), ([o, a]) => isEqualArray(o, a) ).case( ([o, a]) => o == null || a == null || !isObject(o) && !isObject(a), ([o, a]) => o !== o && a !== a ).else(([o, a]) => isEqualObject(o, a)); // src/utils/If.ts function ifTrue(o, f, alt) { return isTrue(o) ? ofConstruct(f, o) : ofConstruct(alt, o); } function ifFalse(o, f, alt) { return !isTrue(o) ? ofConstruct(f, o) : ofConstruct(alt, o); } function ifDefined(o, f, alt) { return isDefined(o) ? ofConstruct(f, o) : ofConstruct(alt); } function ifNotEmpty(o, f = (o2) => o2, alt) { return isNotEmpty(o) ? ofConstruct(f, o) : ofConstruct(alt, o); } function ifEqual(one, another, f, alt) { return isEqual(one, another) ? ofConstruct(f) : ofConstruct(alt); } function ifEither(os, f = (o) => o, alt) { return use( toList(os).first((o) => isPresent(o)), (o) => isDefined(o) ? ofConstruct(f, o) : ofConstruct(alt, o) ); } // src/types/List.ts var List8 = class extends Array { get ids() { return this.mapDefined((i) => i.id); } get indexed() { return this.map((v, index) => ({ ...v, index })); } isSubSetOf(...items) { return this.diff(items).length === 0; } isSuperSetOf(...items) { return this.length > items.length && toList(...items).isSubSetOf(...this); } isIntersectingWith(...items) { return this.intersect(items).length > 0; } isDisjointWith(...items) { return !this.isIntersectingWith(...items); } areEqual(...items) { return this.isSubSetOf(...items) && toList(...items).isSubSetOf(...this); } asc(p) { return toList(...this).sort((e1, e2) => ofProperty(e1, p) > ofProperty(e2, p) ? 1 : -1); } desc(p) { return toList(...this).sort((e1, e2) => ofProperty(e1, p) < ofProperty(e2, p) ? 1 : -1); } first(p, params) { return p ? this.find(p, params) : this[0]; } firstValue(f, alt) { return ifDefined( this.first((t) => !!f(t)), f, (v) => ofGet(alt, v) ); } isFirst(value) { return value === this.first(); } next(p, params) { return p ? this[this.findIndex(p, params) + 1] : this[0]; } prev(p, params) { return p ? this[this.findIndex(p, params) - 1] : this[0]; } last(p, params) { return p ? this.filter(p, params).last() : this[this.length - 1]; } isLast(value) { return value === this.last(); } overlaps(...items) { return toList(...items).some((i) => this.some((t) => i === t)); } diff(others) { return this.filter((i) => !others.includes(i)); } diffByKey(others, key) { return this.filter((i) => !others.some((o) => o[key] === i[key])); } symmetricDiff(others) { return this.diff(others).concat(toList(...others).diff(this)); } symmetricDiffByKey(others, key) { return this.diffByKey(others, key).concat(toList(...others).diffByKey(this, key)); } intersect(others) { return this.filter((i) => others.includes(i)); } intersectByKey(others, key) { return this.filter((i) => others.some((o) => o[key] === i[key])); } intersectBy(others, f) { return this.filter((i) => others.some((o) => f(i, o))); } accumulate(...keys2) { return this.map((d, i, arr) => { const acc = keys2.reduce((acc2, v) => { acc2[v] = i === 0 ? d[v] : arr[i - 1][v] + d[v]; return acc2; }, d); arr[i] = acc; return acc; }); } toJSON() { return this.reduce((a, i) => { a.push(JSON.parse(JSON.stringify(i ?? {}))); return a; }, new Array()); } map(f, params) { return toList(super.map(f, params)); } flatMap(f, params) { return toList(super.flatMap(f, params)); } mapDefined(f, params) { return this.map(f, params).defined(); } mapAsync(f) { return Promise.all(super.map((e) => f(e))).then((a) => toList(a)); } mapSerial(f) { return super.reduce((p, item) => p.then((results) => on(results, async (r) => r.push(await f(item)))), Promise.resolve(toList())); } distinct() { return this.filter((i, index) => this.indexOf(i) === index); } distinctByKey(key) { const seen = /* @__PURE__ */ new Set(); return this.filter((item) => !seen.has(item[key]) && seen.add(item[key])); } distinctByValue() { const seen = /* @__PURE__ */ new Set(); return this.filter((item) => !seen.has(JSON.stringify(item)) && seen.add(JSON.stringify(item))); } filter(p, params) { return toList(super.filter(p, params)); } sum(p) { return this.reduce((sum, i) => sum + p(i), 0); } max(p) { return this.desc(p).first(); } min(p) { return this.asc(p).first(); } byId(id) { return this.first((i) => equals(i.id, id)); } byKey(key, value) { return this.first((i) => i[key] == value); } add(...items) { super.push(...toArray(...items)); return this; } concat(...items) { return toList(super.concat(...items)); } reverse() { return toList(super.reverse()); } splice(start, deleteCount, ...items) { return toList(super.splice(start, deleteCount, ...items)); } remove(item) { const index = this.indexOf(item); if (index > -1) { this.splice(index, 1); } return this; } move(sourceId, destinationId) { return this.moveOn("id", sourceId, destinationId); } moveOn(key, sourceId, destinationId) { const source = this.findIndex((i) => equals(i[key], sourceId)); const dest = this.findIndex((i) => equals(i[key], destinationId)); return on(toList(...this), (r) => r.splice(dest, 0, ...r.splice(source, 1))); } replace(key, item) { const index = this.findIndex((i) => i[key] === item?.[key]); ifTrue(index != -1, () => this.splice(index, 1, item)); return this; } switch(item) { return this.includes(item) ? this.remove(item) : this.add(item); } switchOn(item, on2) { return use( typeof on2 === "function" ? this.find(on2) : use(traverse(item, on2), (v) => this.find((i) => traverse(i, on2) === v)), (i) => i ? this.remove(i) : this.add(item) ); } defined() { return this.reduce((l, v) => isDefined(v) ? l.add(v) : l, toList()); } toObject(key, options = {}) { return this.reduce((o, i) => { o[i[key]] = i; if (options.deleteKey) delete o[i[key]][key]; return o; }, {}); } toObjectList(key) { return this.reduce( (a, t) => { const k = t[key]; a[k] = a[k] ?? toList(); a[k].push(t); return a; }, {} ); } orElse(...alt) { return !isEmpty(this) ? this : !isEmpty(...alt) ? toList(...alt) : void 0; } weave(insertFrom, interval) { for (let i = interval, n = 0; i <= this.length && n < insertFrom.length; i += interval + 1) { this.splice(i, 0, insertFrom[n++]); } return this; } slice(start, end) { return toList(super.slice(start, end)); } none(p) { return !this.some(p); } chunk(chunkSize) { return this.reduce((acc, _, index) => index % chunkSize === 0 ? on(acc, (a) => a.push(this.slice(index, index + chunkSize))) : acc, toList()); } //we needed to add U because of a Typescript issue with generics update(p, val) { return this.map((v, i, a) => p(v, i, a) ? ofGet(val, v, i, a) : v); } updateFirst(p, val) { const index = this.findIndex(p); return this.update((t, i) => p(t, i, this) && i == index, val); } updateFirstById(id, val) { return this.updateFirst((i) => equals(i?.id, id), val); } updateById(id, val) { return this.update((i) => equals(i?.id, id), val); } groupBy(by) { return toList( Array.from(this.reduce((m, v, i, a) => use(by(v, i, a), (key) => m.set(key, (m.get(key) ?? toList()).add(v))), /* @__PURE__ */ new Map()).values()) ); } }; var toList = (...items) => new List8().add(...items); var isList = (l) => isDefined(l) && isArray(l) && isA(l, "first", "last", "asc", "desc"); var asList = (c, items = []) => toList(toArray(items).map((i) => new c(i))); var maxValue = (l, key) => l.desc(key).first()?.[key]; var minValue = (l, key) => l.asc(key).first()?.[key]; export { List8 as List, toList, isList, asList, maxValue, minValue, entries, values, keys, extractKeys, resolve, reject, tuple, tuple2, tuple3, tuple4, tuple5, tupleO, settled, meta, isEnumConstructor, Enum, isEnum, Try, tryTo, Template, template, ToText, text, textValue, Exception, isException, isDoesNotExist, When, when, DotEnvContext, BaseRequestContext, BaseContext, Context, ctx, toResult, isResult, Results, toResults, isResults, asResults, validate, validateReject, isValid, choose, isEqual, ifTrue, ifFalse, ifDefined, ifNotEmpty, ifEqual, ifEither }; //# sourceMappingURL=chunk-AVHYDITZ.mjs.map