@thisisagile/easy-mongo
Version:
Add support for MongoDB
157 lines (155 loc) • 5.38 kB
JavaScript
import {
toMongoType
} from "./chunk-MZE7UWQC.mjs";
// src/MongoProvider.ts
import {
asJson,
asNumber,
asString,
choose,
entries,
Exception,
ifTrue,
isArray,
isDefined,
isField,
isSortCondition,
json,
toArray,
toPageList,
tuple2,
tuple3,
use,
when
} from "@thisisagile/easy";
import {
MongoClient
} from "mongodb";
var omitId = (j) => json.delete(j, "_id");
function omitOptions(obj) {
const { maxTimeMS, ...rest } = obj ?? {};
return rest;
}
var MongoProvider = class _MongoProvider {
constructor(coll) {
this.coll = coll;
}
static clients = {};
static destroyAll() {
return Promise.all(entries(_MongoProvider.clients).map(([u, c]) => c.then((c2) => c2.close()).then(() => delete _MongoProvider.clients[u]))).then(
() => void 0
);
}
static connect(u, db) {
return MongoClient.connect(u, {
auth: {
username: asString(db.options?.user),
password: asString(db.options?.password)
},
...db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize },
...db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize },
...db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS },
...db.options?.socketTimeoutMS && { socketTimeoutMS: db.options?.socketTimeoutMS }
}).then((c) => {
c.on("error", () => delete _MongoProvider.clients[u]);
c.on("close", () => delete _MongoProvider.clients[u]);
return c;
}).catch((err) => {
delete _MongoProvider.clients[u];
return Promise.reject(err);
});
}
cluster() {
return use(
this.coll.db,
(db) => when(db.options?.cluster).not.isDefined.reject(Exception.IsNotValid.because("Missing cluster in database options.")).then((c) => _MongoProvider.clients[c] ?? (_MongoProvider.clients[c] = _MongoProvider.connect(c, db)))
);
}
collection() {
return this.cluster().then((c) => c.db(this.coll.db.name)).then((db) => db.collection(asString(this.coll)));
}
toMongoJson(query) {
return toMongoType(asJson(query));
}
withTimeout(options) {
return { ...options, maxTimeMS: options?.maxTimeMS ?? this.coll.db?.options?.queryTimeoutMS ?? 3e4 };
}
find(query, options) {
return tuple3(this.collection(), this.toMongoJson(query), this.toFindOptions(options)).then(
([c, q, o]) => tuple2(
c.find(q, o),
ifTrue(o.total, () => c.countDocuments(q, { maxTimeMS: this.withTimeout(options).maxTimeMS }))
)
).then(([res, total]) => this.toArray(res, { ...omitOptions(options), total }));
}
all(options) {
return this.find({}, options);
}
byId(id, options) {
return this.collection().then((c) => c.findOne(this.toMongoJson({ id }), this.toFindOptions(options)));
}
by(key, value, options) {
return this.find({ [key]: value }, options);
}
group(qs, options) {
return this.aggregate(qs, options);
}
aggregate(qs, options) {
return this.collection().then(
(c) => c.aggregate(
qs.map((q) => this.toMongoJson(q)),
this.withTimeout(options)
)
).then((res) => this.toArray(res));
}
add(item) {
return this.collection().then((c) => c.insertOne(omitId(item))).then(() => omitId(item));
}
update(item) {
return this.collection().then((c) => c.updateOne(this.toMongoJson({ id: item.id }), { $set: omitId(item) })).then(() => this.byId(item.id));
}
remove(id) {
return this.collection().then((c) => c.deleteOne(this.toMongoJson({ id }))).then((d) => d.acknowledged);
}
count(query, options) {
return this.collection().then((c) => c.countDocuments(this.toMongoJson(query ?? {}), this.withTimeout(options)));
}
createIndex(indexes, options) {
return this.collection().then((c) => c.createIndex(this.toIndexSpecification(indexes), this.toCreateIndexesOptions(options)));
}
createPartialIndex(indexes, filter, options) {
return this.createIndex(indexes, { ...options, filter });
}
createTextIndex(indexes, options) {
const ii = toArray(indexes).reduce((i, f) => ({ ...i, [asString(f)]: "text" }), {});
return this.createIndex(ii, { unique: false, ...options });
}
toFindOptions(options) {
return {
limit: asNumber(options?.take ?? 250),
...options?.skip && { skip: asNumber(options?.skip) },
...options?.sorts && { sort: options?.sorts } || options?.sort && { sort: this.coll.sort(...options?.sort ?? []) },
total: isDefined(options?.skip) || isDefined(options?.take),
projection: options?.projection ?? { _id: 0 },
maxTimeMS: this.withTimeout(options).maxTimeMS
};
}
toIndexSpecification(index) {
return choose(index).type(isField, (f) => f.property).type(isSortCondition, (s) => s.toJSON()).type(isArray, (aa) => aa.map((a) => this.toIndexSpecification(a))).else((i) => i);
}
toCreateIndexesOptions(options) {
return {
unique: options?.unique ?? true,
...options?.languageOverride && { language_override: options.languageOverride },
...options?.languageDefault && { default_language: options.languageDefault },
...options?.filter && { partialFilterExpression: toMongoType(asJson(options.filter)) }
};
}
toArray(cursor, options) {
return cursor.toArray().then((r) => toPageList(r, options));
}
};
export {
MongoProvider
};
//# sourceMappingURL=chunk-P372VCR6.mjs.map