UNPKG

@thisisagile/easy-mongo

Version:
157 lines (155 loc) • 5.38 kB
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