@thisisagile/easy
Version:
Straightforward library for building domain-driven microservice architectures
1,619 lines (1,585 loc) • 114 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc2) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __decorateClass = (decorators, target, key, kind) => {
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
for (var i = decorators.length - 1, decorator; i >= 0; i--)
if (decorator = decorators[i])
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
if (kind && result)
__defProp(target, key, result);
return result;
};
// src/index.ts
var src_exports = {};
__export(src_exports, {
Api: () => Api,
ApiGateway: () => ApiGateway,
App: () => App,
Audit: () => Audit,
AxiosProvider: () => AxiosProvider,
BaseContext: () => BaseContext,
BaseRequestContext: () => BaseRequestContext,
CacheControl: () => CacheControl,
Child: () => Child,
Clause: () => Clause,
Column: () => Column,
Condition: () => Condition,
ContentType: () => ContentType,
Context: () => Context,
Convert: () => Convert,
Database: () => Database,
DateTime: () => DateTime,
DefaultProvider: () => DefaultProvider,
Delete: () => Delete,
DotEnvContext: () => DotEnvContext,
EasyUri: () => EasyUri,
Entity: () => Entity,
Enum: () => Enum,
Environment: () => Environment,
Exception: () => Exception,
Field: () => Field,
Gateway: () => Gateway,
HttpHeader: () => HttpHeader,
HttpStatus: () => HttpStatus,
HttpVerb: () => HttpVerb,
InMemoryGateway: () => InMemoryGateway,
Insert: () => Insert,
Join: () => Join,
Jwt: () => Jwt,
List: () => List,
LogicalCondition: () => LogicalCondition,
Manage: () => Manage,
MappedRouteGateway: () => MappedRouteGateway,
Mapper: () => Mapper,
OrderColumn: () => OrderColumn,
PageList: () => PageList,
ParathesizedClause: () => ParathesizedClause,
Parser: () => Parser,
PatternColumn: () => PatternColumn,
Property: () => Property,
Repo: () => Repo,
Repository: () => Repository,
Req: () => Req,
RequestOptions: () => RequestOptions,
Results: () => Results,
RouteGateway: () => RouteGateway,
Scope: () => Scope,
Search: () => Search,
Select: () => Select,
Sentence: () => Sentence,
SortCondition: () => SortCondition,
SqlQuery: () => SqlQuery,
State: () => State,
Struct: () => Struct,
Table: () => Table,
TableGateway: () => TableGateway,
Template: () => Template,
ToText: () => ToText,
Try: () => Try,
Typo: () => Typo,
Update: () => Update,
UseCase: () => UseCase,
Value: () => Value,
View: () => View,
ViewRouteGateway: () => ViewRouteGateway,
Wait: () => Wait,
When: () => When,
accumulate: () => accumulate,
any: () => any,
api: () => api,
array: () => array,
asJson: () => asJson,
asList: () => asList,
asNumber: () => asNumber,
asPageList: () => asPageList,
asResults: () => asResults,
asString: () => asString,
asc: () => asc,
base64: () => base64,
build: () => build,
cache: () => cache,
cacheAge: () => cacheAge,
capitalize: () => capitalize,
choose: () => choose,
clipUri: () => clipUri,
constraint: () => constraint,
convert: () => convert,
ctx: () => ctx,
days: () => days,
defined: () => defined,
desc: () => desc,
dir: () => dir,
dt: () => dt,
entries: () => entries,
extractKeys: () => extractKeys,
future: () => future,
gt: () => gt,
gte: () => gte,
ifA: () => ifA,
ifDefined: () => ifDefined,
ifFalse: () => ifFalse,
ifGet: () => ifGet,
ifNotEmpty: () => ifNotEmpty,
ifTrue: () => ifTrue,
inFuture: () => inFuture,
inList: () => inList,
inOptionalList: () => inOptionalList,
inPast: () => inPast,
includes: () => includes,
isA: () => isA,
isAn: () => isAn,
isArray: () => isArray,
isBoolean: () => isBoolean,
isCacheAge: () => isCacheAge,
isClause: () => isClause,
isConstructor: () => isConstructor,
isCurrency: () => isCurrency,
isDate: () => isDate,
isDateTime: () => isDateTime,
isDefined: () => isDefined,
isDoesNotExist: () => isDoesNotExist,
isEmpty: () => isEmpty,
isEmptyObject: () => isEmptyObject,
isEnum: () => isEnum,
isEqual: () => isEqual,
isError: () => isError,
isException: () => isException,
isFalsy: () => isFalsy,
isField: () => isField,
isFunc: () => isFunc,
isFunction: () => isFunction,
isHttpStatus: () => isHttpStatus,
isIdentity: () => isIdentity,
isIn: () => isIn,
isInstance: () => isInstance,
isIntersecting: () => isIntersecting,
isIsoDateString: () => isIsoDateString,
isJson: () => isJson,
isList: () => isList,
isLoading: () => isLoading,
isMapping: () => isMapping,
isNotEmpty: () => isNotEmpty,
isNotPresent: () => isNotPresent,
isNullish: () => isNullish,
isNumber: () => isNumber,
isObject: () => isObject,
isPageList: () => isPageList,
isPresent: () => isPresent,
isPrimitive: () => isPrimitive,
isRequestOptions: () => isRequestOptions,
isResponse: () => isResponse,
isRestResult: () => isRestResult,
isResult: () => isResult,
isResults: () => isResults,
isSimpleView: () => isSimpleView,
isSortCondition: () => isSortCondition,
isString: () => isString,
isStruct: () => isStruct,
isText: () => isText,
isTrue: () => isTrue,
isTruthy: () => isTruthy,
isUndefined: () => isUndefined,
isUuid: () => isUuid,
isValid: () => isValid,
isValidatable: () => isValidatable,
isValue: () => isValue,
json: () => json,
kebab: () => kebab,
keys: () => keys,
log: () => log,
lt: () => lt,
lte: () => lte,
mappings: () => mappings,
maxLength: () => maxLength,
maxValue: () => maxValue,
meta: () => meta,
minLength: () => minLength,
minValue: () => minValue,
notEmpty: () => notEmpty,
ofConstruct: () => ofConstruct,
ofGet: () => ofGet,
ofMessage: () => ofMessage,
ofProperty: () => ofProperty,
on: () => on,
optional: () => optional,
past: () => past,
quote: () => quote,
reject: () => reject,
replaceAll: () => replaceAll,
required: () => required,
resolve: () => resolve,
rest: () => rest,
rule: () => rule,
searchable: () => searchable,
seconds: () => seconds,
settled: () => settled,
singleton: () => singleton,
tag: () => tag,
takeFirstKey: () => takeFirstKey,
template: () => template,
text: () => text,
textValue: () => textValue,
toArray: () => toArray,
toCacheOptions: () => toCacheOptions,
toClause: () => toClause,
toCondition: () => toCondition,
toFilter: () => toFilter,
toHttpStatus: () => toHttpStatus,
toId: () => toId,
toJson: () => toJson,
toList: () => toList,
toName: () => toName,
toObject: () => toObject,
toPageList: () => toPageList,
toPageOptions: () => toPageOptions,
toReq: () => toReq,
toResponse: () => toResponse,
toResult: () => toResult,
toResults: () => toResults,
toSegment: () => toSegment,
toShortFilter: () => toShortFilter,
toUuid: () => toUuid,
toViewer: () => toViewer,
toWords: () => toWords,
traverse: () => traverse,
traverseSet: () => traverseSet,
tryTo: () => tryTo,
tuple: () => tuple,
tuple2: () => tuple2,
tuple3: () => tuple3,
tuple4: () => tuple4,
tuple5: () => tuple5,
uri: () => uri,
use: () => use,
valid: () => valid,
validate: () => validate,
validateReject: () => validateReject,
values: () => values,
view: () => view,
views: () => views,
wait: () => wait,
we: () => we,
when: () => when
});
module.exports = __toCommonJS(src_exports);
// src/types/Is.ts
var isDefined = (o) => o !== void 0 && o !== null;
var isUndefined = (v) => v === void 0 || v === null;
var isEmpty = (o) => o === "" || o === null || o === void 0 || isArray(o) && o.length === 0;
var isNotEmpty = (o) => o !== "" && o !== null && o !== void 0 && (!isArray(o) || o.length > 0);
var isString = (o) => o instanceof String || typeof o === "string";
var isIsoDateString = (o) => isString(o) && /^\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)$/.test(o);
var isBoolean = (o) => isDefined(o) && typeof o === "boolean";
var isTrue = (o) => isFunction(o) ? isTrue(o()) : isBoolean(o) ? o : !!o;
var isNumber = (o) => isDefined(o) && typeof o === "number" && !Number.isNaN(o);
var isObject = (o) => o != null && typeof o === "object" && !isArray(o);
var isEmptyObject = (o) => isObject(o) && Object.getOwnPropertyNames(o).length === 0;
var isFunction = (o) => isDefined(o) && typeof o === "function";
var isArray = (o) => isDefined(o) && o instanceof Array;
var isIn = (o, values2) => isArray(values2) && values2.some((v) => v === o);
var isIntersecting = (o, values2) => isArray(o) && isArray(values2) && o.some((ov) => isIn(ov, values2));
var isError = (e) => isDefined(e) && e instanceof Error;
var isNotPresent = (...os) => os.some(
(o) => o === null || o === void 0 || o === "" || o instanceof Array && o.length === 0 || typeof o === "object" && Object.getOwnPropertyNames(o).length === 0
);
var isPresent = (...os) => !isNotPresent(...os);
// src/types/Primitive.ts
var isPrimitive = (v) => {
return v === null || v === void 0 || isIn(typeof v, ["string", "number", "bigint", "boolean", "symbol"]);
};
// src/types/Func.ts
var isFunc = (o) => !!o && typeof o === "function";
// src/types/Constructor.ts
var isConstructor = (c) => (isDefined(c) && isFunc(c) && c.prototype && c.prototype.constructor) === c;
var isInstance = (ctor, o) => isFunction(ctor) && o instanceof ctor;
var ofConstruct = (c, ...args) => isConstructor(c) ? new c(...args) : isFunc(c) ? c(...args) : c;
var toName = (subject, postfix = "") => subject?.constructor?.name?.replace(postfix, "").toLowerCase() ?? "";
var isPromise = (value) => {
return value instanceof Promise;
};
var on = (t, f) => {
const result = f(t);
return isPromise(result) ? result.then(() => t) : t;
};
var use = (t, f) => f(t);
var ifA = (c, t, alt) => !isPrimitive(t) && t instanceof c ? t : alt ? ifA(c, alt) : void 0;
// src/types/IsA.ts
var isA = (t, ...properties) => !isPrimitive(t) && properties.every((p) => p.toString() in t);
var isAn = isA;
var isIdentity = (by) => use(by, (b) => isObject(b) && isDefined(b.id));
// src/types/Get.ts
var ofGet = (g, ...args) => isFunc(g) ? g(...args) : g;
var ifGet = (pred, valid2, invalid) => ofGet(pred) ? ofGet(valid2) : ofGet(invalid);
var ofProperty = (t, p) => isFunc(p) ? p(t) : t[p];
// 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);
}
// src/types/Array.ts
var toArray = (...items) => items.length > 1 ? items : isArray(items[0]) ? items[0] : isDefined(items[0]) ? [items[0]] : [];
var toObject = (key, ...items) => toArray(...items).reduce((o, i) => {
o[i[key]] = i;
return o;
}, {});
var array = {
merge: (first = [], second = [], firstKey = "id", secondKey = "id") => first.map((f) => ({
...f,
...second.find((s) => isDefined(s[secondKey]) && isDefined(f[firstKey]) && s[secondKey] === f[firstKey])
})),
switch: (items = [], item) => use([...items], (res) => {
on(res.indexOf(item), (i) => i !== -1 ? res.splice(i, 1) : res.push(item));
return res;
}),
splitIn: (items = [], length = 2) => {
const res = Array.from({ length }, () => []);
items.forEach((i, index) => res[index % length].push(i));
return res;
},
chunk: (items = [], length = 2) => {
const chunks = Math.ceil(items.length / length);
const res = Array.from({ length: chunks }, () => []);
items.forEach((i, index) => res[Math.floor(index / chunks)].push(i));
return res;
}
};
// src/types/Text.ts
var isText = (t) => isDefined(t) && isFunc(t.toString);
var asString = (t, alt = "") => (isText(t) ? t : ofGet(alt)).toString();
var replaceAll = (origin, search, replace = "") => asString(origin).split(asString(search)).join(asString(replace));
var toWords = (input) => {
return asString(input).replace(/(\p{Lower})(\p{Upper})/gu, "$1 $2").replace(/(\p{Upper})(\p{Upper}\p{Lower})/gu, "$1 $2").split(/[_\W]+/g).filter(Boolean);
};
var kebab = (s = "") => toWords(s).join("-").toLowerCase();
var capitalize = (s = "") => s.charAt(0).toUpperCase() + s.slice(1);
// src/types/List.ts
var List = class extends Array {
get ids() {
return this.mapDefined((i) => i.id);
}
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 this.sort((e1, e2) => ofProperty(e1, p) > ofProperty(e2, p) ? 1 : -1);
}
desc(p) {
return 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(key) {
return this.desc(key).first();
}
min(key) {
return this.asc(key).first();
}
byId(id) {
return this.first((i) => asString(i.id) === asString(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;
}
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);
}
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) => asString(i?.id) === asString(id), val);
}
updateById(id, val) {
return this.update((i) => asString(i?.id) === asString(id), val);
}
};
var toList = (...items) => new List().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];
// 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/types/Json.ts
var isJson = (subject) => isA(subject, "toJSON");
var json = {
parse: (subject) => JSON.parse(JSON.stringify(subject ?? {})),
merge: (...subjects) => json.parse(subjects.map((s) => asJson(s, (s2) => json.parse(s2))).reduce((js, j) => ({ ...js, ...j }), {})),
delete: (subject, key) => {
ifDefined(subject, () => delete subject[key]);
return subject;
},
set: (subject, key = "", value) => isEmpty(key) ? subject : value !== void 0 ? { ...subject, ...{ [key]: value } } : json.delete(subject, key),
omit: (subject, ...keys2) => keys2.reduce((js, k) => json.delete(js, k), json.parse(subject)),
pick: (subject, ...keys2) => keys2.reduce((js, k) => json.set(js, k, subject[k]), {}),
defaults: (options = {}, defaults = {}) => json.merge(defaults, options),
isSubset: (subject, subset) => !entries(subset).some(([k, v]) => subject[k] !== v)
};
var toJson = json.merge;
var asJson = (j, alt = {}) => isJson(j) ? j.toJSON() : isObject(j) ? j : ofGet(alt, j);
var Any = class {
constructor(value) {
this.value = value;
}
merge = (...subjects) => any(json.merge(this.value, ...subjects));
delete = (key) => any(json.delete(this.value, key));
omit = (...keys2) => any(json.omit(this.value, ...keys2));
set = (key, value) => any(json.set(this.value, key, value));
toJSON() {
return this.value;
}
};
var takeFirstKey = (j, alt = "") => entries(asJson(j)).first()?.[0] ?? alt;
var any = (value) => new Any(value);
// src/utils/Convert.ts
var Convert = class {
constructor(from, to) {
this.from = from;
this.to = to;
}
};
var convert = {
default: new Convert(
(a) => a,
(a) => a
),
ignore: new Convert(
() => void 0,
() => void 0
),
toBool: {
fromNumber: new Convert(
(b) => b ? 1 : 0,
(n) => n !== 0
),
fromString: new Convert(
(b) => b ? "true" : "false",
(s) => s === "true"
)
},
toDate: {
fromString: new Convert(
(s) => new Date(s).toISOString(),
(s) => s
)
},
toNumber: {
fromString: new Convert(
(n) => asString(n),
(s) => parseInt(s)
)
}
};
// src/data/Condition.ts
var Condition = class {
constructor(key, operator, value) {
this.key = key;
this.operator = operator;
this.value = value;
}
and = (...others) => new LogicalCondition("and", [this, ...others]);
or = (...others) => new LogicalCondition("or", [this, ...others]);
toJSON() {
return { [this.key]: { [`$${this.operator}`]: json.parse(this.value) } };
}
};
var LogicalCondition = class {
constructor(operator, conditions) {
this.operator = operator;
this.conditions = conditions;
}
toJSON() {
return { [`$${this.operator}`]: this.conditions.map((c) => c.toJSON()) };
}
};
var SortCondition = class extends Condition {
constructor(key, value) {
super(key, "", value);
this.key = key;
this.value = value;
}
toJSON() {
return { [this.key]: this.value };
}
};
var toCondition = (field, operator, value, conv = convert.default) => new Condition(field, operator, conv.from(value));
var isSortCondition = (s) => isDefined(s) && s instanceof SortCondition;
// src/types/Meta.ts
var import_reflect_metadata = require("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 Enum = class {
constructor(name, id = name.toLowerCase(), code = id.toString()) {
this.name = name;
this.id = id;
this.code = code;
}
get isValid() {
return isDefined(this.id);
}
static all() {
return meta(this.allTuple()).values();
}
static allTuple() {
return meta(this).get(`all-${this.name}`) ?? meta(this).set(`all-${this.name}`, meta(this).values().filter(isEnum).toObject("id"));
}
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);
}
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/Template.ts
var Template = class {
constructor(template2, subject = {}, options = {}) {
this.template = template2;
this.subject = subject;
this.options = options;
}
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 = () => {
return this.props(this.template, "this").reduce((t, p) => t.replace(`{${p}}`, textValue(this.subject, p.replace("this.", ""))), this.template);
};
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, {
type: toName(subject),
subject: text(JSON.stringify(subject)),
...options
});
}
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 isEmpty() {
return isEmpty(this.toString());
}
parse = (subject, options = {}) => text(template(this.subject, subject, { type: toName(subject), ...options }));
is = (...others) => others.some((o) => this.toString() === text(o).toString());
equals = this.is;
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) => 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/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)))
}))
};
var tuple2 = tuple[2];
var tuple3 = tuple[3];
var tuple4 = tuple[4];
var tuple5 = tuple[5];
var settled = tuple.settled;
// src/types/Gateway.ts
var Gateway = class {
all(options) {
return reject(Exception.IsNotImplemented);
}
byId(id, options) {
return reject(Exception.IsNotImplemented);
}
by(_key, _value, _options) {
return reject(Exception.IsNotImplemented);
}
byIds(..._ids) {
return reject(Exception.IsNotImplemented);
}
search(q, options) {
return reject(Exception.IsNotImplemented);
}
filter(options) {
return reject(Exception.IsNotImplemented);
}
exists(id, options) {
return reject(Exception.IsNotImplemented);
}
add(item, options) {
return reject(Exception.IsNotImplemented);
}
update(item, options) {
return reject(Exception.IsNotImplemented);
}
remove(id, options) {
return reject(Exception.IsNotImplemented);
}
};
// src/validation/When.ts
var When = class _When {
constructor(subject, valid2 = true, results) {
this.subject = subject;
this.valid = valid2;
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/types/Value.ts
var Value = class {
constructor(value) {
this.value = value;
this.value = value;
}
get isValid() {
return isDefined(this.value);
}
toJSON() {
return this.value;
}
toString() {
return asString(this.value);
}
};
var isValue = (v) => v instanceof Value;
// src/types/Validatable.ts
var isValidatable = (v) => isA(v, "isValid");
// 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 constraint2 = v.constraint(actual);
return isResults(constraint2) ? constraint2 : !constraint2 ? 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/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/types/PageList.ts
var toFilter = (field, value) => toShortFilter(field, field, value);
var toShortFilter = (field, shortField, value) => ({
field,
shortField,
values: [{ value }]
});
var PageList = class extends List {
_options;
get options() {
return this._options;
}
get take() {
return this._options?.take ?? 250;
}
get skip() {
return this._options?.skip ?? 0;
}
get total() {
return this._options?.total;
}
get sorts() {
return this._options?.sorts;
}
get filters() {
return this._options?.filters;
}
get meta() {
return {
take: this.take,
skip: this.skip,
total: this.total,
sorts: this.sorts,
filters: this.filters
};
}
get ids() {
return this.mapDefined((i) => i.id);
}
asc(p) {
return toPageList(super.asc(p), this);
}
desc(p) {
return toPageList(super.desc(p), this);
}
diff(others) {
return toPageList(super.diff(others), this);
}
diffByKey(others, key) {
return toPageList(super.diffByKey(others, key), this);
}
symmetricDiff(others) {
return toPageList(super.symmetricDiff(others), this);
}
symmetricDiffByKey(others, key) {
return toPageList(super.symmetricDiffByKey(others, key), this);
}
intersect(others) {
return toPageList(super.intersect(others), this);
}
intersectByKey(others, key) {
return toPageList(super.intersectByKey(others, key), this);
}
map(f, params) {
const items = super.map(f, params);
return toPageList(items, this);
}
flatMap(f, params) {
return toPageList(super.flatMap(f, params), this);
}
mapDefined(f, params) {
return toPageList(super.mapDefined(f, params), this);
}
mapAsync(f) {
return super.mapAsync(f).then((r) => toPageList(r, this));
}
areEqual(...items) {
return this.isSubSetOf(...items) && toList(...items).isSubSetOf(...this);
}
distinct() {
return toPageList(super.distinct(), this);
}
distinctByKey(key) {
return toPageList(super.distinctByKey(key), this);
}
distinctByValue() {
return toPageList(super.distinctByValue(), this);
}
filter(p, params) {
return toPageList(super.filter(p, params), this);
}
accumulate(...keys2) {
return toPageList(super.accumulate(...keys2), this);
}
concat(...items) {
return toPageList(super.concat(...items), this);
}
reverse() {
return toPageList(super.reverse(), this);
}
splice(start, deleteCount, ...items) {
return toPageList(super.splice(start, deleteCount, ...items), this);
}
remove(item) {
return toPageList(super.remove(item), this);
}
replace(key, item) {
return toPageList(super.replace(key, item), this);
}
switch(item) {
return toPageList(super.switch(item), this);
}
defined() {
return toPageList(super.defined(), this);
}
orElse(...alt) {
return toPageList(super.orElse(...alt), this);
}
slice(start, end) {
return toPageList(super.slice(start, end), this);
}
//we needed to add U because of a Typescript issue with generics
update(p, val) {
return toPageList(super.update(p, val), this);
}
updateFirst(p, val) {
return toPageList(super.updateFirst(p, val), this);
}
updateFirstById(id, val) {
return toPageList(super.updateFirstById(id, val), this);
}
updateById(id, val) {
return toPageList(super.updateById(id, val), this);
}
setPageOptions(options) {
this._options = options;
return this;
}
};
var isPageList = (l) => isList(l) && isA(l, "total");
var toPageList = (items = [], options) => choose(items).case(
(i) => i.length === 1 && isNumber(i[0]),
(i) => new PageList().add(...i)
).else((i) => new PageList(...i)).setPageOptions(options);
var asPageList = (c, items = toPageList()) => items.map((i) => ofConstruct(c, i));
// src/data/InMemoryGateway.ts
var InMemoryGateway = class extends Gateway {
constructor(data) {
super();
this.data = data;
}
all(options) {
return this.data.then((d) => toPageList(d, d));
}
byId(id) {
return this.data.then((d) => d.byId(id)).then((d) => d ? { ...d } : void 0);
}
by = (key, value) => {
return this.data.then((d) => d.filter((i) => i[key] === value));
};
exists(id) {
return this.byId(id).then((d) => isDefined(d));
}
add(item) {
return when(item).not.contains((i) => i.id).reject(Exception.IsMissingId).then((i) => this.exists(i.id)).then((ex) => when(ex).isTrue.reject(Exception.AlreadyExists)).then(() => this.data.then((d) => d.add(item))).then(() => ({ ...item }));
}
remove(id) {
return this.data.then(
(d) => when(d.findIndex((i) => i.id === id)).with((i) => i < 0).reject(Exception.DoesNotExist).then((i) => d.splice(i, 1))
).then(() => true);
}
update(item) {
return when(item).not.contains((i) => i.id).reject(Exception.IsMissingId).then((i) => this.remove(i.id).then(() => this.add(i)));
}
};
// src/data/Database.ts
var DefaultProvider = class {
};
var Database = class _Database extends Enum {
constructor(name, provider, options) {
super(name);
this.provider = provider;
this.options = options;
}
static Default = new _Database("Default", DefaultProvider);
provide = () => ofConstruct(this.provider, this);
};
// src/utils/Property.ts
var Property = class {
constructor(property, options) {
this.property = property;
this.options = options;
this.options = { ...options, convert: options?.convert ?? convert.default };
}
in = (source = {}) => this.options?.convert?.to(source[this.property] ?? ofGet(this.options?.dflt));
out = (source = {}, key = "") => this.options?.convert?.from(source[key]);
toString