@thisisagile/easy-mongo 15.23.6 → 15.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/MongoProvider.d.ts +6 -6
- package/dist/MongoProvider.js +25 -22
- package/dist/MongoProvider.js.map +1 -1
- package/dist/MongoProvider.mjs +25 -23
- package/dist/MongoProvider.mjs.map +1 -1
- package/package.json +3 -3
- package/src/MongoProvider.ts +34 -37
package/dist/MongoProvider.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Condition,
|
|
1
|
+
import { Condition, FetchOptions, Field, Id, Json, JsonValue, LogicalCondition, OneOrMore, PageList, Sort } from '@thisisagile/easy';
|
|
2
2
|
import { AggregationCursor, Collection as MongoCollection, CreateIndexesOptions, Document, FindCursor, FindOptions as MongoFindOptions, IndexSpecification, MongoClient, StrictFilter as MongoFilter } from 'mongodb';
|
|
3
3
|
import { Collection } from './Collection';
|
|
4
4
|
export type Projection = Record<string, 0 | 1>;
|
|
@@ -16,13 +16,14 @@ export type IndexOptions = {
|
|
|
16
16
|
export type Indexes = OneOrMore<string | Field | Sort | Record<string, 1 | -1>>;
|
|
17
17
|
export declare class MongoProvider {
|
|
18
18
|
readonly coll: Collection;
|
|
19
|
-
protected client?: Promise<MongoClient> | undefined;
|
|
20
19
|
protected static readonly clients: {
|
|
21
|
-
[key: string]:
|
|
20
|
+
[key: string]: MongoClient;
|
|
22
21
|
};
|
|
23
|
-
constructor(coll: Collection
|
|
24
|
-
static client(db: Database): Promise<MongoClient>;
|
|
22
|
+
constructor(coll: Collection);
|
|
25
23
|
cluster(): Promise<MongoClient>;
|
|
24
|
+
collection<T extends Document = Document>(): Promise<MongoCollection<T>>;
|
|
25
|
+
private static connect;
|
|
26
|
+
static disconnect(): void;
|
|
26
27
|
toMongoJson(query: Query): Json;
|
|
27
28
|
find(query: Query, options?: FindOptions): Promise<PageList<Json>>;
|
|
28
29
|
all(options?: FindOptions): Promise<PageList<Json>>;
|
|
@@ -37,7 +38,6 @@ export declare class MongoProvider {
|
|
|
37
38
|
createIndex(indexes: Indexes, options?: IndexOptions): Promise<string>;
|
|
38
39
|
createPartialIndex(indexes: Indexes, filter: Query, options?: Omit<IndexOptions, 'filter'>): Promise<string>;
|
|
39
40
|
createTextIndex(indexes: OneOrMore<Field | string>, options?: IndexOptions): Promise<string>;
|
|
40
|
-
collection<T extends Document = Document>(): Promise<MongoCollection<T>>;
|
|
41
41
|
protected toFindOptions(options?: FindOptions): MongoFindOptions & {
|
|
42
42
|
total: boolean;
|
|
43
43
|
};
|
package/dist/MongoProvider.js
CHANGED
|
@@ -26,30 +26,36 @@ var import_mongodb = require("mongodb");
|
|
|
26
26
|
var import_Utils = require("./Utils");
|
|
27
27
|
const omitId = (j) => import_easy.json.delete(j, "_id");
|
|
28
28
|
class MongoProvider {
|
|
29
|
-
constructor(coll
|
|
29
|
+
constructor(coll) {
|
|
30
30
|
this.coll = coll;
|
|
31
|
-
this.client = client;
|
|
32
31
|
}
|
|
33
32
|
static clients = {};
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
33
|
+
async cluster() {
|
|
34
|
+
const db = this.coll.db;
|
|
35
|
+
const c = await (0, import_easy.when)(db.options?.cluster).not.isDefined.reject(import_easy.Exception.IsNotValid.because("Missing cluster in database options."));
|
|
36
|
+
return MongoProvider.clients[c] ?? (MongoProvider.clients[c] = await MongoProvider.connect(c, db));
|
|
37
|
+
}
|
|
38
|
+
collection() {
|
|
39
|
+
return this.cluster().then((c) => c.db(this.coll.db.name)).then((db) => db.collection((0, import_easy.asString)(this.coll)));
|
|
40
|
+
}
|
|
41
|
+
static connect(u, db) {
|
|
42
|
+
return import_mongodb.MongoClient.connect(u, {
|
|
43
|
+
auth: {
|
|
44
|
+
username: (0, import_easy.asString)(db.options?.user),
|
|
45
|
+
password: (0, import_easy.asString)(db.options?.password)
|
|
46
|
+
},
|
|
47
|
+
...db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize },
|
|
48
|
+
...db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize },
|
|
49
|
+
...db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }
|
|
50
|
+
}).then((c) => {
|
|
51
|
+
c.on("error", () => delete MongoProvider.clients[u]);
|
|
52
|
+
c.on("close", () => delete MongoProvider.clients[u]);
|
|
53
|
+
return c;
|
|
51
54
|
});
|
|
52
55
|
}
|
|
56
|
+
static disconnect() {
|
|
57
|
+
Object.values(MongoProvider.clients).forEach((c) => void c.close());
|
|
58
|
+
}
|
|
53
59
|
toMongoJson(query) {
|
|
54
60
|
return (0, import_Utils.toMongoType)((0, import_easy.asJson)(query));
|
|
55
61
|
}
|
|
@@ -98,9 +104,6 @@ class MongoProvider {
|
|
|
98
104
|
const ii = (0, import_easy.toArray)(indexes).reduce((i, f) => ({ ...i, [(0, import_easy.asString)(f)]: "text" }), {});
|
|
99
105
|
return this.createIndex(ii, { unique: false, ...options });
|
|
100
106
|
}
|
|
101
|
-
collection() {
|
|
102
|
-
return this.cluster().then((c) => c.db(this.coll.db.name)).then((db) => db.collection((0, import_easy.asString)(this.coll)));
|
|
103
|
-
}
|
|
104
107
|
toFindOptions(options) {
|
|
105
108
|
return {
|
|
106
109
|
limit: (0, import_easy.asNumber)(options?.take ?? 250),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/MongoProvider.ts"],"sourcesContent":["import {\n asJson,\n asNumber,\n asString,\n choose,\n Condition,\n Database,\n Exception,\n FetchOptions,\n Field,\n Id,\n ifTrue,\n isArray,\n isDefined,\n isField,\n isSortCondition,\n json,\n Json,\n JsonValue,\n LogicalCondition,\n OneOrMore,\n PageList,\n reject,\n Sort,\n toArray,\n toPageList,\n tuple2,\n tuple3,\n when,\n} from '@thisisagile/easy';\nimport {\n AggregationCursor,\n Collection as MongoCollection,\n CreateIndexesOptions,\n Document,\n FindCursor,\n FindOptions as MongoFindOptions,\n IndexSpecification,\n MongoClient,\n StrictFilter as MongoFilter,\n} from 'mongodb';\nimport { Collection } from './Collection';\nimport { toMongoType } from './Utils';\n\nconst omitId = (j: Json): Json => json.delete(j, '_id');\n\nexport type Projection = Record<string, 0 | 1>;\nexport type FindOptions = FetchOptions & { projection?: Projection };\nexport type Filter<T = unknown> = MongoFilter<T>;\nexport type Query = Condition | LogicalCondition | Filter<any>;\n\nexport type IndexOptions = {\n unique?: boolean;\n filter?: Query;\n languageOverride?: string;\n languageDefault?: string;\n};\n\nexport type Indexes = OneOrMore<string | Field | Sort | Record<string, 1 | -1>>;\n\nexport class MongoProvider {\n protected static readonly clients: { [key: string]: Promise<MongoClient> } = {};\n\n constructor(readonly coll: Collection, protected client?: Promise<MongoClient>) {}\n\n static client(db: Database): Promise<MongoClient> {\n return when(db.options?.cluster)\n .not.isDefined.reject(Exception.IsNotValid.because('Missing cluster in database options.'))\n .then(\n u =>\n (MongoProvider.clients[u] =\n MongoProvider.clients[u] ??\n MongoClient.connect(u, {\n auth: {\n username: asString(db.options?.user),\n password: asString(db.options?.password),\n },\n ...(db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize }),\n ...(db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize }),\n ...(db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }),\n }))\n );\n }\n\n cluster(): Promise<MongoClient> {\n return Promise.resolve()\n .then(() => this.client ?? (this.client = MongoProvider.client(this.coll.db)))\n .catch(e => {\n this.client = undefined;\n return reject(e);\n });\n }\n\n toMongoJson(query: Query): Json {\n return toMongoType(asJson(query));\n }\n\n find(query: Query, options?: FindOptions): Promise<PageList<Json>> {\n return tuple3(this.collection(), this.toMongoJson(query), this.toFindOptions(options))\n .then(([c, q, o]) =>\n tuple2(\n c.find(q, o),\n ifTrue(o.total, () => c.countDocuments(q))\n )\n )\n .then(([res, total]) => this.toArray(res, { ...options, total }));\n }\n\n all(options?: FindOptions): Promise<PageList<Json>> {\n return this.find({}, options);\n }\n\n byId(id: Id, options?: FindOptions): Promise<Json> {\n return this.collection().then(c => c.findOne(this.toMongoJson({ id: id }), this.toFindOptions(options)) as Promise<Json>);\n }\n\n by(key: string, value: JsonValue, options?: FindOptions): Promise<PageList<Json>> {\n return this.find({ [key]: value }, options);\n }\n\n group(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.aggregate(qs);\n }\n\n aggregate(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.collection()\n .then(c => c.aggregate(qs.map(q => this.toMongoJson(q))))\n .then(res => this.toArray(res));\n }\n\n add(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.insertOne(omitId(item)))\n .then(() => omitId(item));\n }\n\n update(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.updateOne(this.toMongoJson({ id: item.id }), { $set: omitId(item) }))\n .then(() => this.byId(item.id as Id));\n }\n\n remove(id: Id): Promise<boolean> {\n return this.collection()\n .then(c => c.deleteOne(this.toMongoJson({ id })))\n .then(d => d.acknowledged);\n }\n\n count(query?: Query): Promise<number> {\n return this.collection().then(c => c.countDocuments(this.toMongoJson(query ?? {})));\n }\n\n createIndex(indexes: Indexes, options?: IndexOptions): Promise<string> {\n return this.collection().then(c => c.createIndex(this.toIndexSpecification(indexes), this.toCreateIndexesOptions(options)));\n }\n\n createPartialIndex(indexes: Indexes, filter: Query, options?: Omit<IndexOptions, 'filter'>): Promise<string> {\n return this.createIndex(indexes, { ...options, filter });\n }\n\n createTextIndex(indexes: OneOrMore<Field | string>, options?: IndexOptions): Promise<string> {\n const ii = toArray(indexes).reduce((i, f) => ({ ...i, [asString(f)]: 'text' }), {});\n return this.createIndex(ii, { unique: false, ...options });\n }\n\n collection<T extends Document = Document>(): Promise<MongoCollection<T>> {\n return this.cluster()\n .then(c => c.db(this.coll.db.name))\n .then(db => db.collection<T>(asString(this.coll)));\n }\n\n protected toFindOptions(options?: FindOptions): MongoFindOptions & { total: boolean } {\n return {\n limit: asNumber(options?.take ?? 250),\n ...(options?.skip && { skip: asNumber(options?.skip) }),\n ...((options?.sorts && { sort: options?.sorts }) || (options?.sort && { sort: this.coll.sort(...(options?.sort ?? [])) })),\n total: isDefined(options?.skip) || isDefined(options?.take),\n projection: options?.projection ?? { _id: 0 },\n };\n }\n\n protected toIndexSpecification(index: Indexes): IndexSpecification {\n return choose(index)\n .type(isField, f => f.property as IndexSpecification)\n .type(isSortCondition, s => s.toJSON() as IndexSpecification)\n .type(isArray, aa => aa.map(a => this.toIndexSpecification(a)) as IndexSpecification)\n .else(i => i as IndexSpecification);\n }\n\n protected toCreateIndexesOptions(options?: IndexOptions): CreateIndexesOptions {\n return {\n unique: options?.unique ?? true,\n ...(options?.languageOverride && { language_override: options.languageOverride }),\n ...(options?.languageDefault && { default_language: options.languageDefault }),\n ...(options?.filter && { partialFilterExpression: toMongoType(asJson(options.filter)) }),\n };\n }\n\n protected toArray(\n cursor: FindCursor<Document> | AggregationCursor<Document>,\n options?: { take?: number; skip?: number; total?: number }\n ): Promise<PageList<Json>> {\n return cursor.toArray().then(r => toPageList<Json>(r, options));\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBA6BO;AACP,qBAUO;AAEP,mBAA4B;AAE5B,MAAM,SAAS,CAAC,MAAkB,iBAAK,OAAO,GAAG,KAAK;AAgB/C,MAAM,cAAc;AAAA,EAGzB,YAAqB,MAA4B,QAA+B;AAA3D;AAA4B;AAAA,EAAgC;AAAA,EAFjF,OAA0B,UAAmD,CAAC;AAAA,EAI9E,OAAO,OAAO,IAAoC;AAChD,eAAO,kBAAK,GAAG,SAAS,OAAO,EAC5B,IAAI,UAAU,OAAO,sBAAU,WAAW,QAAQ,sCAAsC,CAAC,EACzF;AAAA,MACC,OACG,cAAc,QAAQ,CAAC,IACtB,cAAc,QAAQ,CAAC,KACvB,2BAAY,QAAQ,GAAG;AAAA,QACrB,MAAM;AAAA,UACJ,cAAU,sBAAS,GAAG,SAAS,IAAI;AAAA,UACnC,cAAU,sBAAS,GAAG,SAAS,QAAQ;AAAA,QACzC;AAAA,QACA,GAAI,GAAG,SAAS,eAAe,EAAE,aAAa,GAAG,SAAS,YAAY;AAAA,QACtE,GAAI,GAAG,SAAS,eAAe,EAAE,aAAa,GAAG,SAAS,YAAY;AAAA,QACtE,GAAI,GAAG,SAAS,iBAAiB,EAAE,eAAe,GAAG,SAAS,cAAc;AAAA,MAC9E,CAAC;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,UAAgC;AAC9B,WAAO,QAAQ,QAAQ,EACpB,KAAK,MAAM,KAAK,WAAW,KAAK,SAAS,cAAc,OAAO,KAAK,KAAK,EAAE,EAAE,EAC5E,MAAM,OAAK;AACV,WAAK,SAAS;AACd,iBAAO,oBAAO,CAAC;AAAA,IACjB,CAAC;AAAA,EACL;AAAA,EAEA,YAAY,OAAoB;AAC9B,eAAO,8BAAY,oBAAO,KAAK,CAAC;AAAA,EAClC;AAAA,EAEA,KAAK,OAAc,SAAgD;AACjE,eAAO,oBAAO,KAAK,WAAW,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,cAAc,OAAO,CAAC,EAClF;AAAA,MAAK,CAAC,CAAC,GAAG,GAAG,CAAC,UACb;AAAA,QACE,EAAE,KAAK,GAAG,CAAC;AAAA,YACX,oBAAO,EAAE,OAAO,MAAM,EAAE,eAAe,CAAC,CAAC;AAAA,MAC3C;AAAA,IACF,EACC,KAAK,CAAC,CAAC,KAAK,KAAK,MAAM,KAAK,QAAQ,KAAK,EAAE,GAAG,SAAS,MAAM,CAAC,CAAC;AAAA,EACpE;AAAA,EAEA,IAAI,SAAgD;AAClD,WAAO,KAAK,KAAK,CAAC,GAAG,OAAO;AAAA,EAC9B;AAAA,EAEA,KAAK,IAAQ,SAAsC;AACjD,WAAO,KAAK,WAAW,EAAE,KAAK,OAAK,EAAE,QAAQ,KAAK,YAAY,EAAE,GAAO,CAAC,GAAG,KAAK,cAAc,OAAO,CAAC,CAAkB;AAAA,EAC1H;AAAA,EAEA,GAAG,KAAa,OAAkB,SAAgD;AAChF,WAAO,KAAK,KAAK,EAAE,CAAC,GAAG,GAAG,MAAM,GAAG,OAAO;AAAA,EAC5C;AAAA,EAEA,MAAM,IAA4C;AAChD,WAAO,KAAK,UAAU,EAAE;AAAA,EAC1B;AAAA,EAEA,UAAU,IAA4C;AACpD,WAAO,KAAK,WAAW,EACpB,KAAK,OAAK,EAAE,UAAU,GAAG,IAAI,OAAK,KAAK,YAAY,CAAC,CAAC,CAAC,CAAC,EACvD,KAAK,SAAO,KAAK,QAAQ,GAAG,CAAC;AAAA,EAClC;AAAA,EAEA,IAAI,MAA2B;AAC7B,WAAO,KAAK,WAAW,EACpB,KAAK,OAAK,EAAE,UAAU,OAAO,IAAI,CAAC,CAAC,EACnC,KAAK,MAAM,OAAO,IAAI,CAAC;AAAA,EAC5B;AAAA,EAEA,OAAO,MAA2B;AAChC,WAAO,KAAK,WAAW,EACpB,KAAK,OAAK,EAAE,UAAU,KAAK,YAAY,EAAE,IAAI,KAAK,GAAG,CAAC,GAAG,EAAE,MAAM,OAAO,IAAI,EAAE,CAAC,CAAC,EAChF,KAAK,MAAM,KAAK,KAAK,KAAK,EAAQ,CAAC;AAAA,EACxC;AAAA,EAEA,OAAO,IAA0B;AAC/B,WAAO,KAAK,WAAW,EACpB,KAAK,OAAK,EAAE,UAAU,KAAK,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,EAC/C,KAAK,OAAK,EAAE,YAAY;AAAA,EAC7B;AAAA,EAEA,MAAM,OAAgC;AACpC,WAAO,KAAK,WAAW,EAAE,KAAK,OAAK,EAAE,eAAe,KAAK,YAAY,SAAS,CAAC,CAAC,CAAC,CAAC;AAAA,EACpF;AAAA,EAEA,YAAY,SAAkB,SAAyC;AACrE,WAAO,KAAK,WAAW,EAAE,KAAK,OAAK,EAAE,YAAY,KAAK,qBAAqB,OAAO,GAAG,KAAK,uBAAuB,OAAO,CAAC,CAAC;AAAA,EAC5H;AAAA,EAEA,mBAAmB,SAAkB,QAAe,SAAyD;AAC3G,WAAO,KAAK,YAAY,SAAS,EAAE,GAAG,SAAS,OAAO,CAAC;AAAA,EACzD;AAAA,EAEA,gBAAgB,SAAoC,SAAyC;AAC3F,UAAM,SAAK,qBAAQ,OAAO,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,KAAC,sBAAS,CAAC,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;AAClF,WAAO,KAAK,YAAY,IAAI,EAAE,QAAQ,OAAO,GAAG,QAAQ,CAAC;AAAA,EAC3D;AAAA,EAEA,aAAyE;AACvE,WAAO,KAAK,QAAQ,EACjB,KAAK,OAAK,EAAE,GAAG,KAAK,KAAK,GAAG,IAAI,CAAC,EACjC,KAAK,QAAM,GAAG,eAAc,sBAAS,KAAK,IAAI,CAAC,CAAC;AAAA,EACrD;AAAA,EAEU,cAAc,SAA8D;AACpF,WAAO;AAAA,MACL,WAAO,sBAAS,SAAS,QAAQ,GAAG;AAAA,MACpC,GAAI,SAAS,QAAQ,EAAE,UAAM,sBAAS,SAAS,IAAI,EAAE;AAAA,MACrD,GAAK,SAAS,SAAS,EAAE,MAAM,SAAS,MAAM,KAAO,SAAS,QAAQ,EAAE,MAAM,KAAK,KAAK,KAAK,GAAI,SAAS,QAAQ,CAAC,CAAE,EAAE;AAAA,MACvH,WAAO,uBAAU,SAAS,IAAI,SAAK,uBAAU,SAAS,IAAI;AAAA,MAC1D,YAAY,SAAS,cAAc,EAAE,KAAK,EAAE;AAAA,IAC9C;AAAA,EACF;AAAA,EAEU,qBAAqB,OAAoC;AACjE,eAAO,oBAAO,KAAK,EAChB,KAAK,qBAAS,OAAK,EAAE,QAA8B,EACnD,KAAK,6BAAiB,OAAK,EAAE,OAAO,CAAuB,EAC3D,KAAK,qBAAS,QAAM,GAAG,IAAI,OAAK,KAAK,qBAAqB,CAAC,CAAC,CAAuB,EACnF,KAAK,OAAK,CAAuB;AAAA,EACtC;AAAA,EAEU,uBAAuB,SAA8C;AAC7E,WAAO;AAAA,MACL,QAAQ,SAAS,UAAU;AAAA,MAC3B,GAAI,SAAS,oBAAoB,EAAE,mBAAmB,QAAQ,iBAAiB;AAAA,MAC/E,GAAI,SAAS,mBAAmB,EAAE,kBAAkB,QAAQ,gBAAgB;AAAA,MAC5E,GAAI,SAAS,UAAU,EAAE,6BAAyB,8BAAY,oBAAO,QAAQ,MAAM,CAAC,EAAE;AAAA,IACxF;AAAA,EACF;AAAA,EAEU,QACR,QACA,SACyB;AACzB,WAAO,OAAO,QAAQ,EAAE,KAAK,WAAK,wBAAiB,GAAG,OAAO,CAAC;AAAA,EAChE;AACF;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/MongoProvider.ts"],"sourcesContent":["import {\n asJson,\n asNumber,\n asString,\n choose,\n Condition,\n Database,\n Exception,\n FetchOptions,\n Field,\n Id,\n ifTrue,\n isArray,\n isDefined,\n isField,\n isSortCondition,\n json,\n Json,\n JsonValue,\n LogicalCondition,\n OneOrMore,\n PageList,\n Sort,\n toArray,\n toPageList,\n tuple2,\n tuple3,\n when,\n} from '@thisisagile/easy';\nimport {\n AggregationCursor,\n Collection as MongoCollection,\n CreateIndexesOptions,\n Document,\n FindCursor,\n FindOptions as MongoFindOptions,\n IndexSpecification,\n MongoClient,\n StrictFilter as MongoFilter,\n} from 'mongodb';\nimport { Collection } from './Collection';\nimport { toMongoType } from './Utils';\n\nconst omitId = (j: Json): Json => json.delete(j, '_id');\n\nexport type Projection = Record<string, 0 | 1>;\nexport type FindOptions = FetchOptions & { projection?: Projection };\nexport type Filter<T = unknown> = MongoFilter<T>;\nexport type Query = Condition | LogicalCondition | Filter<any>;\n\nexport type IndexOptions = {\n unique?: boolean;\n filter?: Query;\n languageOverride?: string;\n languageDefault?: string;\n};\n\nexport type Indexes = OneOrMore<string | Field | Sort | Record<string, 1 | -1>>;\n\nexport class MongoProvider {\n protected static readonly clients: { [key: string]: MongoClient } = {};\n\n constructor(readonly coll: Collection) {}\n\n async cluster(): Promise<MongoClient> {\n const db = this.coll.db;\n const c = await when(db.options?.cluster).not.isDefined.reject(Exception.IsNotValid.because('Missing cluster in database options.'));\n return MongoProvider.clients[c] ?? (MongoProvider.clients[c] = await MongoProvider.connect(c, db));\n }\n\n collection<T extends Document = Document>(): Promise<MongoCollection<T>> {\n return this.cluster()\n .then(c => c.db(this.coll.db.name))\n .then(db => db.collection<T>(asString(this.coll)));\n }\n\n private static connect(u: string, db: Database) {\n return MongoClient.connect(u, {\n auth: {\n username: asString(db.options?.user),\n password: asString(db.options?.password),\n },\n ...(db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize }),\n ...(db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize }),\n ...(db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }),\n }).then(c => {\n c.on('error', () => delete MongoProvider.clients[u]);\n c.on('close', () => delete MongoProvider.clients[u]);\n return c;\n });\n }\n\n static disconnect() {\n Object.values(MongoProvider.clients).forEach(c => void c.close());\n }\n\n toMongoJson(query: Query): Json {\n return toMongoType(asJson(query));\n }\n\n find(query: Query, options?: FindOptions): Promise<PageList<Json>> {\n return tuple3(this.collection(), this.toMongoJson(query), this.toFindOptions(options))\n .then(([c, q, o]) =>\n tuple2(\n c.find(q, o),\n ifTrue(o.total, () => c.countDocuments(q))\n )\n )\n .then(([res, total]) => this.toArray(res, { ...options, total }));\n }\n\n all(options?: FindOptions): Promise<PageList<Json>> {\n return this.find({}, options);\n }\n\n byId(id: Id, options?: FindOptions): Promise<Json> {\n return this.collection().then(c => c.findOne(this.toMongoJson({ id: id }), this.toFindOptions(options)) as Promise<Json>);\n }\n\n by(key: string, value: JsonValue, options?: FindOptions): Promise<PageList<Json>> {\n return this.find({ [key]: value }, options);\n }\n\n group(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.aggregate(qs);\n }\n\n aggregate(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.collection()\n .then(c => c.aggregate(qs.map(q => this.toMongoJson(q))))\n .then(res => this.toArray(res));\n }\n\n add(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.insertOne(omitId(item)))\n .then(() => omitId(item));\n }\n\n update(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.updateOne(this.toMongoJson({ id: item.id }), { $set: omitId(item) }))\n .then(() => this.byId(item.id as Id));\n }\n\n remove(id: Id): Promise<boolean> {\n return this.collection()\n .then(c => c.deleteOne(this.toMongoJson({ id })))\n .then(d => d.acknowledged);\n }\n\n count(query?: Query): Promise<number> {\n return this.collection().then(c => c.countDocuments(this.toMongoJson(query ?? {})));\n }\n\n createIndex(indexes: Indexes, options?: IndexOptions): Promise<string> {\n return this.collection().then(c => c.createIndex(this.toIndexSpecification(indexes), this.toCreateIndexesOptions(options)));\n }\n\n createPartialIndex(indexes: Indexes, filter: Query, options?: Omit<IndexOptions, 'filter'>): Promise<string> {\n return this.createIndex(indexes, { ...options, filter });\n }\n\n createTextIndex(indexes: OneOrMore<Field | string>, options?: IndexOptions): Promise<string> {\n const ii = toArray(indexes).reduce((i, f) => ({ ...i, [asString(f)]: 'text' }), {});\n return this.createIndex(ii, { unique: false, ...options });\n }\n\n protected toFindOptions(options?: FindOptions): MongoFindOptions & { total: boolean } {\n return {\n limit: asNumber(options?.take ?? 250),\n ...(options?.skip && { skip: asNumber(options?.skip) }),\n ...((options?.sorts && { sort: options?.sorts }) || (options?.sort && { sort: this.coll.sort(...(options?.sort ?? [])) })),\n total: isDefined(options?.skip) || isDefined(options?.take),\n projection: options?.projection ?? { _id: 0 },\n };\n }\n\n protected toIndexSpecification(index: Indexes): IndexSpecification {\n return choose(index)\n .type(isField, f => f.property as IndexSpecification)\n .type(isSortCondition, s => s.toJSON() as IndexSpecification)\n .type(isArray, aa => aa.map(a => this.toIndexSpecification(a)) as IndexSpecification)\n .else(i => i as IndexSpecification);\n }\n\n protected toCreateIndexesOptions(options?: IndexOptions): CreateIndexesOptions {\n return {\n unique: options?.unique ?? true,\n ...(options?.languageOverride && { language_override: options.languageOverride }),\n ...(options?.languageDefault && { default_language: options.languageDefault }),\n ...(options?.filter && { partialFilterExpression: toMongoType(asJson(options.filter)) }),\n };\n }\n\n protected toArray(\n cursor: FindCursor<Document> | AggregationCursor<Document>,\n options?: { take?: number; skip?: number; total?: number }\n ): Promise<PageList<Json>> {\n return cursor.toArray().then(r => toPageList<Json>(r, options));\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/MongoProvider.mjs
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
isField,
|
|
11
11
|
isSortCondition,
|
|
12
12
|
json,
|
|
13
|
-
reject,
|
|
14
13
|
toArray,
|
|
15
14
|
toPageList,
|
|
16
15
|
tuple2,
|
|
@@ -23,30 +22,36 @@ import {
|
|
|
23
22
|
import { toMongoType } from "./Utils";
|
|
24
23
|
const omitId = (j) => json.delete(j, "_id");
|
|
25
24
|
class MongoProvider {
|
|
26
|
-
constructor(coll
|
|
25
|
+
constructor(coll) {
|
|
27
26
|
this.coll = coll;
|
|
28
|
-
this.client = client;
|
|
29
27
|
}
|
|
30
28
|
static clients = {};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
29
|
+
async cluster() {
|
|
30
|
+
const db = this.coll.db;
|
|
31
|
+
const c = await when(db.options?.cluster).not.isDefined.reject(Exception.IsNotValid.because("Missing cluster in database options."));
|
|
32
|
+
return MongoProvider.clients[c] ?? (MongoProvider.clients[c] = await MongoProvider.connect(c, db));
|
|
33
|
+
}
|
|
34
|
+
collection() {
|
|
35
|
+
return this.cluster().then((c) => c.db(this.coll.db.name)).then((db) => db.collection(asString(this.coll)));
|
|
36
|
+
}
|
|
37
|
+
static connect(u, db) {
|
|
38
|
+
return MongoClient.connect(u, {
|
|
39
|
+
auth: {
|
|
40
|
+
username: asString(db.options?.user),
|
|
41
|
+
password: asString(db.options?.password)
|
|
42
|
+
},
|
|
43
|
+
...db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize },
|
|
44
|
+
...db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize },
|
|
45
|
+
...db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }
|
|
46
|
+
}).then((c) => {
|
|
47
|
+
c.on("error", () => delete MongoProvider.clients[u]);
|
|
48
|
+
c.on("close", () => delete MongoProvider.clients[u]);
|
|
49
|
+
return c;
|
|
48
50
|
});
|
|
49
51
|
}
|
|
52
|
+
static disconnect() {
|
|
53
|
+
Object.values(MongoProvider.clients).forEach((c) => void c.close());
|
|
54
|
+
}
|
|
50
55
|
toMongoJson(query) {
|
|
51
56
|
return toMongoType(asJson(query));
|
|
52
57
|
}
|
|
@@ -95,9 +100,6 @@ class MongoProvider {
|
|
|
95
100
|
const ii = toArray(indexes).reduce((i, f) => ({ ...i, [asString(f)]: "text" }), {});
|
|
96
101
|
return this.createIndex(ii, { unique: false, ...options });
|
|
97
102
|
}
|
|
98
|
-
collection() {
|
|
99
|
-
return this.cluster().then((c) => c.db(this.coll.db.name)).then((db) => db.collection(asString(this.coll)));
|
|
100
|
-
}
|
|
101
103
|
toFindOptions(options) {
|
|
102
104
|
return {
|
|
103
105
|
limit: asNumber(options?.take ?? 250),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/MongoProvider.ts"],"sourcesContent":["import {\n asJson,\n asNumber,\n asString,\n choose,\n Condition,\n Database,\n Exception,\n FetchOptions,\n Field,\n Id,\n ifTrue,\n isArray,\n isDefined,\n isField,\n isSortCondition,\n json,\n Json,\n JsonValue,\n LogicalCondition,\n OneOrMore,\n PageList,\n reject,\n Sort,\n toArray,\n toPageList,\n tuple2,\n tuple3,\n when,\n} from '@thisisagile/easy';\nimport {\n AggregationCursor,\n Collection as MongoCollection,\n CreateIndexesOptions,\n Document,\n FindCursor,\n FindOptions as MongoFindOptions,\n IndexSpecification,\n MongoClient,\n StrictFilter as MongoFilter,\n} from 'mongodb';\nimport { Collection } from './Collection';\nimport { toMongoType } from './Utils';\n\nconst omitId = (j: Json): Json => json.delete(j, '_id');\n\nexport type Projection = Record<string, 0 | 1>;\nexport type FindOptions = FetchOptions & { projection?: Projection };\nexport type Filter<T = unknown> = MongoFilter<T>;\nexport type Query = Condition | LogicalCondition | Filter<any>;\n\nexport type IndexOptions = {\n unique?: boolean;\n filter?: Query;\n languageOverride?: string;\n languageDefault?: string;\n};\n\nexport type Indexes = OneOrMore<string | Field | Sort | Record<string, 1 | -1>>;\n\nexport class MongoProvider {\n protected static readonly clients: { [key: string]: Promise<MongoClient> } = {};\n\n constructor(readonly coll: Collection, protected client?: Promise<MongoClient>) {}\n\n static client(db: Database): Promise<MongoClient> {\n return when(db.options?.cluster)\n .not.isDefined.reject(Exception.IsNotValid.because('Missing cluster in database options.'))\n .then(\n u =>\n (MongoProvider.clients[u] =\n MongoProvider.clients[u] ??\n MongoClient.connect(u, {\n auth: {\n username: asString(db.options?.user),\n password: asString(db.options?.password),\n },\n ...(db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize }),\n ...(db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize }),\n ...(db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }),\n }))\n );\n }\n\n cluster(): Promise<MongoClient> {\n return Promise.resolve()\n .then(() => this.client ?? (this.client = MongoProvider.client(this.coll.db)))\n .catch(e => {\n this.client = undefined;\n return reject(e);\n });\n }\n\n toMongoJson(query: Query): Json {\n return toMongoType(asJson(query));\n }\n\n find(query: Query, options?: FindOptions): Promise<PageList<Json>> {\n return tuple3(this.collection(), this.toMongoJson(query), this.toFindOptions(options))\n .then(([c, q, o]) =>\n tuple2(\n c.find(q, o),\n ifTrue(o.total, () => c.countDocuments(q))\n )\n )\n .then(([res, total]) => this.toArray(res, { ...options, total }));\n }\n\n all(options?: FindOptions): Promise<PageList<Json>> {\n return this.find({}, options);\n }\n\n byId(id: Id, options?: FindOptions): Promise<Json> {\n return this.collection().then(c => c.findOne(this.toMongoJson({ id: id }), this.toFindOptions(options)) as Promise<Json>);\n }\n\n by(key: string, value: JsonValue, options?: FindOptions): Promise<PageList<Json>> {\n return this.find({ [key]: value }, options);\n }\n\n group(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.aggregate(qs);\n }\n\n aggregate(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.collection()\n .then(c => c.aggregate(qs.map(q => this.toMongoJson(q))))\n .then(res => this.toArray(res));\n }\n\n add(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.insertOne(omitId(item)))\n .then(() => omitId(item));\n }\n\n update(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.updateOne(this.toMongoJson({ id: item.id }), { $set: omitId(item) }))\n .then(() => this.byId(item.id as Id));\n }\n\n remove(id: Id): Promise<boolean> {\n return this.collection()\n .then(c => c.deleteOne(this.toMongoJson({ id })))\n .then(d => d.acknowledged);\n }\n\n count(query?: Query): Promise<number> {\n return this.collection().then(c => c.countDocuments(this.toMongoJson(query ?? {})));\n }\n\n createIndex(indexes: Indexes, options?: IndexOptions): Promise<string> {\n return this.collection().then(c => c.createIndex(this.toIndexSpecification(indexes), this.toCreateIndexesOptions(options)));\n }\n\n createPartialIndex(indexes: Indexes, filter: Query, options?: Omit<IndexOptions, 'filter'>): Promise<string> {\n return this.createIndex(indexes, { ...options, filter });\n }\n\n createTextIndex(indexes: OneOrMore<Field | string>, options?: IndexOptions): Promise<string> {\n const ii = toArray(indexes).reduce((i, f) => ({ ...i, [asString(f)]: 'text' }), {});\n return this.createIndex(ii, { unique: false, ...options });\n }\n\n collection<T extends Document = Document>(): Promise<MongoCollection<T>> {\n return this.cluster()\n .then(c => c.db(this.coll.db.name))\n .then(db => db.collection<T>(asString(this.coll)));\n }\n\n protected toFindOptions(options?: FindOptions): MongoFindOptions & { total: boolean } {\n return {\n limit: asNumber(options?.take ?? 250),\n ...(options?.skip && { skip: asNumber(options?.skip) }),\n ...((options?.sorts && { sort: options?.sorts }) || (options?.sort && { sort: this.coll.sort(...(options?.sort ?? [])) })),\n total: isDefined(options?.skip) || isDefined(options?.take),\n projection: options?.projection ?? { _id: 0 },\n };\n }\n\n protected toIndexSpecification(index: Indexes): IndexSpecification {\n return choose(index)\n .type(isField, f => f.property as IndexSpecification)\n .type(isSortCondition, s => s.toJSON() as IndexSpecification)\n .type(isArray, aa => aa.map(a => this.toIndexSpecification(a)) as IndexSpecification)\n .else(i => i as IndexSpecification);\n }\n\n protected toCreateIndexesOptions(options?: IndexOptions): CreateIndexesOptions {\n return {\n unique: options?.unique ?? true,\n ...(options?.languageOverride && { language_override: options.languageOverride }),\n ...(options?.languageDefault && { default_language: options.languageDefault }),\n ...(options?.filter && { partialFilterExpression: toMongoType(asJson(options.filter)) }),\n };\n }\n\n protected toArray(\n cursor: FindCursor<Document> | AggregationCursor<Document>,\n options?: { take?: number; skip?: number; total?: number }\n ): Promise<PageList<Json>> {\n return cursor.toArray().then(r => toPageList<Json>(r, options));\n }\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/MongoProvider.ts"],"sourcesContent":["import {\n asJson,\n asNumber,\n asString,\n choose,\n Condition,\n Database,\n Exception,\n FetchOptions,\n Field,\n Id,\n ifTrue,\n isArray,\n isDefined,\n isField,\n isSortCondition,\n json,\n Json,\n JsonValue,\n LogicalCondition,\n OneOrMore,\n PageList,\n Sort,\n toArray,\n toPageList,\n tuple2,\n tuple3,\n when,\n} from '@thisisagile/easy';\nimport {\n AggregationCursor,\n Collection as MongoCollection,\n CreateIndexesOptions,\n Document,\n FindCursor,\n FindOptions as MongoFindOptions,\n IndexSpecification,\n MongoClient,\n StrictFilter as MongoFilter,\n} from 'mongodb';\nimport { Collection } from './Collection';\nimport { toMongoType } from './Utils';\n\nconst omitId = (j: Json): Json => json.delete(j, '_id');\n\nexport type Projection = Record<string, 0 | 1>;\nexport type FindOptions = FetchOptions & { projection?: Projection };\nexport type Filter<T = unknown> = MongoFilter<T>;\nexport type Query = Condition | LogicalCondition | Filter<any>;\n\nexport type IndexOptions = {\n unique?: boolean;\n filter?: Query;\n languageOverride?: string;\n languageDefault?: string;\n};\n\nexport type Indexes = OneOrMore<string | Field | Sort | Record<string, 1 | -1>>;\n\nexport class MongoProvider {\n protected static readonly clients: { [key: string]: MongoClient } = {};\n\n constructor(readonly coll: Collection) {}\n\n async cluster(): Promise<MongoClient> {\n const db = this.coll.db;\n const c = await when(db.options?.cluster).not.isDefined.reject(Exception.IsNotValid.because('Missing cluster in database options.'));\n return MongoProvider.clients[c] ?? (MongoProvider.clients[c] = await MongoProvider.connect(c, db));\n }\n\n collection<T extends Document = Document>(): Promise<MongoCollection<T>> {\n return this.cluster()\n .then(c => c.db(this.coll.db.name))\n .then(db => db.collection<T>(asString(this.coll)));\n }\n\n private static connect(u: string, db: Database) {\n return MongoClient.connect(u, {\n auth: {\n username: asString(db.options?.user),\n password: asString(db.options?.password),\n },\n ...(db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize }),\n ...(db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize }),\n ...(db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }),\n }).then(c => {\n c.on('error', () => delete MongoProvider.clients[u]);\n c.on('close', () => delete MongoProvider.clients[u]);\n return c;\n });\n }\n\n static disconnect() {\n Object.values(MongoProvider.clients).forEach(c => void c.close());\n }\n\n toMongoJson(query: Query): Json {\n return toMongoType(asJson(query));\n }\n\n find(query: Query, options?: FindOptions): Promise<PageList<Json>> {\n return tuple3(this.collection(), this.toMongoJson(query), this.toFindOptions(options))\n .then(([c, q, o]) =>\n tuple2(\n c.find(q, o),\n ifTrue(o.total, () => c.countDocuments(q))\n )\n )\n .then(([res, total]) => this.toArray(res, { ...options, total }));\n }\n\n all(options?: FindOptions): Promise<PageList<Json>> {\n return this.find({}, options);\n }\n\n byId(id: Id, options?: FindOptions): Promise<Json> {\n return this.collection().then(c => c.findOne(this.toMongoJson({ id: id }), this.toFindOptions(options)) as Promise<Json>);\n }\n\n by(key: string, value: JsonValue, options?: FindOptions): Promise<PageList<Json>> {\n return this.find({ [key]: value }, options);\n }\n\n group(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.aggregate(qs);\n }\n\n aggregate(qs: Filter<any>[]): Promise<PageList<Json>> {\n return this.collection()\n .then(c => c.aggregate(qs.map(q => this.toMongoJson(q))))\n .then(res => this.toArray(res));\n }\n\n add(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.insertOne(omitId(item)))\n .then(() => omitId(item));\n }\n\n update(item: Json): Promise<Json> {\n return this.collection()\n .then(c => c.updateOne(this.toMongoJson({ id: item.id }), { $set: omitId(item) }))\n .then(() => this.byId(item.id as Id));\n }\n\n remove(id: Id): Promise<boolean> {\n return this.collection()\n .then(c => c.deleteOne(this.toMongoJson({ id })))\n .then(d => d.acknowledged);\n }\n\n count(query?: Query): Promise<number> {\n return this.collection().then(c => c.countDocuments(this.toMongoJson(query ?? {})));\n }\n\n createIndex(indexes: Indexes, options?: IndexOptions): Promise<string> {\n return this.collection().then(c => c.createIndex(this.toIndexSpecification(indexes), this.toCreateIndexesOptions(options)));\n }\n\n createPartialIndex(indexes: Indexes, filter: Query, options?: Omit<IndexOptions, 'filter'>): Promise<string> {\n return this.createIndex(indexes, { ...options, filter });\n }\n\n createTextIndex(indexes: OneOrMore<Field | string>, options?: IndexOptions): Promise<string> {\n const ii = toArray(indexes).reduce((i, f) => ({ ...i, [asString(f)]: 'text' }), {});\n return this.createIndex(ii, { unique: false, ...options });\n }\n\n protected toFindOptions(options?: FindOptions): MongoFindOptions & { total: boolean } {\n return {\n limit: asNumber(options?.take ?? 250),\n ...(options?.skip && { skip: asNumber(options?.skip) }),\n ...((options?.sorts && { sort: options?.sorts }) || (options?.sort && { sort: this.coll.sort(...(options?.sort ?? [])) })),\n total: isDefined(options?.skip) || isDefined(options?.take),\n projection: options?.projection ?? { _id: 0 },\n };\n }\n\n protected toIndexSpecification(index: Indexes): IndexSpecification {\n return choose(index)\n .type(isField, f => f.property as IndexSpecification)\n .type(isSortCondition, s => s.toJSON() as IndexSpecification)\n .type(isArray, aa => aa.map(a => this.toIndexSpecification(a)) as IndexSpecification)\n .else(i => i as IndexSpecification);\n }\n\n protected toCreateIndexesOptions(options?: IndexOptions): CreateIndexesOptions {\n return {\n unique: options?.unique ?? true,\n ...(options?.languageOverride && { language_override: options.languageOverride }),\n ...(options?.languageDefault && { default_language: options.languageDefault }),\n ...(options?.filter && { partialFilterExpression: toMongoType(asJson(options.filter)) }),\n };\n }\n\n protected toArray(\n cursor: FindCursor<Document> | AggregationCursor<Document>,\n options?: { take?: number; skip?: number; total?: number }\n ): Promise<PageList<Json>> {\n return cursor.toArray().then(r => toPageList<Json>(r, options));\n }\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thisisagile/easy-mongo",
|
|
3
|
-
"version": "15.
|
|
3
|
+
"version": "15.24.0",
|
|
4
4
|
"description": "Add support for MongoDB",
|
|
5
5
|
"author": "Sander Hoogendoorn",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,10 +33,10 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
-
"@thisisagile/easy-test": "15.
|
|
36
|
+
"@thisisagile/easy-test": "15.24.0"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@thisisagile/easy": "^15.
|
|
39
|
+
"@thisisagile/easy": "^15.24.0",
|
|
40
40
|
"mongodb": "^5.6.0"
|
|
41
41
|
}
|
|
42
42
|
}
|
package/src/MongoProvider.ts
CHANGED
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
LogicalCondition,
|
|
21
21
|
OneOrMore,
|
|
22
22
|
PageList,
|
|
23
|
-
reject,
|
|
24
23
|
Sort,
|
|
25
24
|
toArray,
|
|
26
25
|
toPageList,
|
|
@@ -59,36 +58,40 @@ export type IndexOptions = {
|
|
|
59
58
|
export type Indexes = OneOrMore<string | Field | Sort | Record<string, 1 | -1>>;
|
|
60
59
|
|
|
61
60
|
export class MongoProvider {
|
|
62
|
-
protected static readonly clients: { [key: string]:
|
|
63
|
-
|
|
64
|
-
constructor(readonly coll: Collection
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
61
|
+
protected static readonly clients: { [key: string]: MongoClient } = {};
|
|
62
|
+
|
|
63
|
+
constructor(readonly coll: Collection) {}
|
|
64
|
+
|
|
65
|
+
async cluster(): Promise<MongoClient> {
|
|
66
|
+
const db = this.coll.db;
|
|
67
|
+
const c = await when(db.options?.cluster).not.isDefined.reject(Exception.IsNotValid.because('Missing cluster in database options.'));
|
|
68
|
+
return MongoProvider.clients[c] ?? (MongoProvider.clients[c] = await MongoProvider.connect(c, db));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
collection<T extends Document = Document>(): Promise<MongoCollection<T>> {
|
|
72
|
+
return this.cluster()
|
|
73
|
+
.then(c => c.db(this.coll.db.name))
|
|
74
|
+
.then(db => db.collection<T>(asString(this.coll)));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
private static connect(u: string, db: Database) {
|
|
78
|
+
return MongoClient.connect(u, {
|
|
79
|
+
auth: {
|
|
80
|
+
username: asString(db.options?.user),
|
|
81
|
+
password: asString(db.options?.password),
|
|
82
|
+
},
|
|
83
|
+
...(db.options?.maxPoolSize && { maxPoolSize: db.options?.maxPoolSize }),
|
|
84
|
+
...(db.options?.minPoolSize && { minPoolSize: db.options?.minPoolSize }),
|
|
85
|
+
...(db.options?.maxIdleTimeMS && { maxIdleTimeMS: db.options?.maxIdleTimeMS }),
|
|
86
|
+
}).then(c => {
|
|
87
|
+
c.on('error', () => delete MongoProvider.clients[u]);
|
|
88
|
+
c.on('close', () => delete MongoProvider.clients[u]);
|
|
89
|
+
return c;
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
static disconnect() {
|
|
94
|
+
Object.values(MongoProvider.clients).forEach(c => void c.close());
|
|
92
95
|
}
|
|
93
96
|
|
|
94
97
|
toMongoJson(query: Query): Json {
|
|
@@ -163,12 +166,6 @@ export class MongoProvider {
|
|
|
163
166
|
return this.createIndex(ii, { unique: false, ...options });
|
|
164
167
|
}
|
|
165
168
|
|
|
166
|
-
collection<T extends Document = Document>(): Promise<MongoCollection<T>> {
|
|
167
|
-
return this.cluster()
|
|
168
|
-
.then(c => c.db(this.coll.db.name))
|
|
169
|
-
.then(db => db.collection<T>(asString(this.coll)));
|
|
170
|
-
}
|
|
171
|
-
|
|
172
169
|
protected toFindOptions(options?: FindOptions): MongoFindOptions & { total: boolean } {
|
|
173
170
|
return {
|
|
174
171
|
limit: asNumber(options?.take ?? 250),
|