@thisisagile/easy-mongo
Version:
Add support for MongoDB
155 lines (153 loc) • 5.84 kB
JavaScript
import {
toMongoType
} from "./chunk-MZE7UWQC.mjs";
// src/Stages.ts
import {
asNumber,
asString,
ifDefined,
ifNotEmpty,
isDefined,
isPresent,
isPrimitive,
isString,
meta,
ofGet,
on,
toArray,
use
} from "@thisisagile/easy";
var asc = 1;
var desc = -1;
var FilterBuilder = class {
constructor(filters) {
this.filters = filters;
}
from = (q = {}) => stages.match.match(
meta(q).entries().reduce((acc, [key, value]) => ({ ...acc, ...ifDefined(this.filters[key], (f) => f(value)) }), {})
);
};
var SortBuilder = class {
constructor(sorts) {
this.sorts = sorts;
}
get keys() {
return Object.keys(this.sorts);
}
from = (s = {}, alt) => stages.sort.sort(this.sorts[s?.s ?? ""] ?? this.sorts[alt ?? ""]);
};
var IncludeBuilder = class {
constructor(includes) {
this.includes = includes;
}
get keys() {
return Object.keys(this.includes);
}
from = (i = {}, alt) => stages.project.include(...this.includes[i?.i ?? ""] ?? this.includes[alt ?? ""] ?? []);
};
var escapeRegex = (s) => s.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
var stages = {
root: "$$ROOT",
current: "$$CURRENT",
id: "_id",
decode: {
object: (f) => use(Object.entries(f)[0], ([k, v]) => ofGet(v, k)),
fields: (f) => Object.entries(f).reduce((res, [k, v]) => on(res, (r) => ifDefined(ofGet(v, k), (nv) => r[k] = nv)), {}),
fieldsArrays: (f) => Object.entries(f).reduce((res, [k, v]) => on(res, (r) => r[k] = use(toArray(v), (vs) => vs.map((v2) => ofGet(v2, k)))), {}),
id: (f) => isString(f) ? `$${asString(f)}` : isPrimitive(f) ? f : Object.entries(f).map(([k, v]) => ofGet(v, k))[0]
},
match: {
match: (f) => ({ $match: stages.decode.fields(f) }),
filter: (filters) => new FilterBuilder(filters),
or: (...filters) => ({ $or: toArray(filters).map((f) => stages.decode.object(f)) }),
gt: (value) => ({ $gt: value }),
gte: (value) => ({ $gte: value }),
lt: (value) => ({ $lt: value }),
lte: (value) => ({ $lte: value }),
isIn: (value, separator = ",") => ({ $in: isString(value) ? value.split(separator) : value }),
notIn: (value, separator = ",") => ({ $nin: isString(value) ? value.split(separator) : value }),
after: (date) => stages.match.gte(toMongoType(date)),
before: (date) => stages.match.lt(toMongoType(date)),
anywhere: (q) => ({ $regex: escapeRegex(q), $options: "i" }),
money: (currency, value) => (key) => ({
[`${key}.currency`]: currency.id,
...stages.decode.fields({ [`${key}.value`]: value })
})
},
sort: {
sort: ($sort) => isPresent($sort) ? { $sort } : void 0,
sorter: (sorts) => new SortBuilder(sorts),
asc: (key) => stages.sort.sort({ [key]: asc }),
desc: (key) => stages.sort.sort({ [key]: desc })
},
group: {
group: (fields) => ({
by: (by) => ({ $group: Object.assign({ _id: stages.decode.id(by) }, stages.decode.fields(fields)) })
}),
date: (format = "%Y-%m-%d") => (key) => ({ $dateToString: { date: `$${key}`, format } }),
count: () => ({ $count: {} }),
sum: (from) => isDefined(from) ? { $sum: `$${from}` } : { $sum: 1 },
avg: (from) => ({ $avg: `$${from}` }),
multiply: (...multiply) => ({ $multiply: multiply.map((m) => `$${m}`) }),
first: (from) => ({ $first: `$${from}` }),
last: (from) => ({ $last: `$${from}` }),
min: (from) => ({ $min: `$${from}` }),
max: (from) => ({ $max: `$${from}` }),
addToSet: (from) => ({ $addToSet: `$${from}` }),
push: (from = "$ROOT") => ({ $push: `$${from}` }),
size: (from) => ({ $size: `$${from}` })
},
search: {
search: (f) => ifDefined(stages.decode.id(f), ($search) => ({ $search })),
auto: (value) => (key) => ifDefined(value, (v) => ({ autocomplete: { path: key, query: [v] } })),
fuzzy: (value, maxEdits = 1) => (key) => ifDefined(value, (v) => ({
text: {
query: v,
path: key === "wildcard" ? { wildcard: "*" } : key,
fuzzy: { maxEdits }
}
}))
},
set: {
set: (f) => ({ $set: stages.decode.fields(f) }),
score: () => ({ $meta: "searchScore" })
},
skip: {
skip: (o = {}) => ifDefined(o.skip, { $skip: asNumber(o.skip) }),
take: (o = {}) => ifDefined(o.take, { $limit: asNumber(o.take) })
},
project: {
include: (...includes) => ifNotEmpty(includes, (es) => ({ $project: es.reduce((a, b) => ({ ...a, ...isString(b) ? { [b]: 1 } : b }), {}) })),
exclude: (...excludes) => ifNotEmpty(excludes, (es) => ({ $project: es.reduce((a, b) => ({ ...a, ...isString(b) ? { [b]: 0 } : b }), {}) })),
includes: (includes) => new IncludeBuilder(includes),
project: (project) => ifDefined(project, ($project) => ({ $project })),
date: (key, format) => ({ $toDate: `$${key}`, ...ifDefined(format, { format }) }),
duration: (from, to) => ({ $divide: [{ $subtract: [stages.project.date(from), stages.project.date(to)] }, 1e3] })
},
replaceWith: {
replaceWith: (f) => ifDefined(f, { $replaceWith: f }),
merge: (...objects) => ifNotEmpty(objects, (os) => ({ $mergeObjects: os })),
rootAnd: (...objects) => stages.replaceWith.merge(stages.root, ...objects),
currentAnd: (...objects) => stages.replaceWith.merge(stages.current, ...objects),
reroot: (prop) => ({ $replaceRoot: { newRoot: `$${prop}` } }),
concat: (...props) => ifNotEmpty(props, (ps) => ({ $concatArrays: ps.map((p) => `$${p}`) }))
},
facet: {
facet: (f) => ({ $facet: stages.decode.fieldsArrays(f) }),
unwind: (from) => (f) => ({ $unwind: `$${from ?? f}` }),
count: (from) => (f) => ({ $sortByCount: `$${from ?? f}` }),
data: () => []
},
unwind: {
unwind: (prop) => ({ $unwind: `$${prop}` })
}
};
export {
asc,
desc,
FilterBuilder,
SortBuilder,
IncludeBuilder,
stages
};
//# sourceMappingURL=chunk-WEJO6T5Q.mjs.map