@smartsoft001/mongo 2.148.0 → 2.150.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/README.md CHANGED
@@ -1,7 +1,227 @@
1
- # shared-mongo
1
+ # 📦 @smartsoft001/mongo
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ ![npm](https://img.shields.io/npm/v/@smartsoft001/mongo) ![downloads](https://img.shields.io/npm/dm/@smartsoft001/mongo)
4
4
 
5
- ## Running unit tests
5
+ The MongoDB implementation of the storage contracts declared in [@smartsoft001/domain-core](../domain-core/README.md). One module import binds the abstract repositories and the unit of work to classes backed by the MongoDB driver, so application code keeps injecting the abstractions and never names a driver type.
6
6
 
7
- Run `ng test shared-mongo` to execute the unit tests via [Jest](https://jestjs.io).
7
+ ## 🚀 Usage
8
+
9
+ `npm i @smartsoft001/mongo`
10
+
11
+ ```typescript
12
+ import { Module } from '@nestjs/common';
13
+ import { MongoModule } from '@smartsoft001/mongo';
14
+
15
+ @Module({
16
+ imports: [
17
+ MongoModule.forRoot({
18
+ host: 'localhost',
19
+ port: 27017,
20
+ database: 'app',
21
+ collection: 'tasks',
22
+ }),
23
+ ],
24
+ })
25
+ export class DataModule {}
26
+ ```
27
+
28
+ `forRoot` only builds a provider list. Every repository method opens its own connection when it runs and closes it when it finishes, so importing the module reaches no database and a module that imports it can be compiled and inspected offline. There is no `forFeature`: a second database or a second collection means a second `forRoot` in the module that needs it.
29
+
30
+ ## 🔌 What forRoot registers
31
+
32
+ The dynamic module both provides and exports four bindings, so importing it is enough to inject any of them.
33
+
34
+ <table>
35
+ <thead>
36
+ <tr>
37
+ <td>Token</td>
38
+ <td>Bound to</td>
39
+ </tr>
40
+ </thead>
41
+ <tr>
42
+ <td>MongoConfig</td>
43
+ <td>the object you passed in, as a value provider</td>
44
+ </tr>
45
+ <tr>
46
+ <td>IItemRepository</td>
47
+ <td>MongoItemRepository</td>
48
+ </tr>
49
+ <tr>
50
+ <td>IAttachmentRepository</td>
51
+ <td>MongoAttachmentRepository</td>
52
+ </tr>
53
+ <tr>
54
+ <td>IUnitOfWork</td>
55
+ <td>MongoUnitOfWork</td>
56
+ </tr>
57
+ </table>
58
+
59
+ ## ⚙️ MongoConfig
60
+
61
+ A plain class used both as the shape of the argument and as the injection token.
62
+
63
+ <table>
64
+ <thead>
65
+ <tr>
66
+ <td>Field</td>
67
+ <td>Required</td>
68
+ <td>Description</td>
69
+ </tr>
70
+ </thead>
71
+ <tr>
72
+ <td>database: string</td>
73
+ <td>yes</td>
74
+ <td>The database name, also sent as the authSource of the connection string.</td>
75
+ </tr>
76
+ <tr>
77
+ <td>host: string</td>
78
+ <td>no</td>
79
+ <td>The server host. A host ending in ondigitalocean.com switches the connection to mongodb+srv with TLS.</td>
80
+ </tr>
81
+ <tr>
82
+ <td>port: number</td>
83
+ <td>no</td>
84
+ <td>The server port.</td>
85
+ </tr>
86
+ <tr>
87
+ <td>username: string</td>
88
+ <td>no</td>
89
+ <td>Supplied together with password, adds credentials to the connection string.</td>
90
+ </tr>
91
+ <tr>
92
+ <td>password: string</td>
93
+ <td>no</td>
94
+ <td>The password for username.</td>
95
+ </tr>
96
+ <tr>
97
+ <td>collection: string</td>
98
+ <td>no</td>
99
+ <td>The collection the item repository works on, and the GridFS bucket name the attachment repository uses.</td>
100
+ </tr>
101
+ <tr>
102
+ <td>type: any</td>
103
+ <td>no</td>
104
+ <td>The model class of the stored entity. Its @Field metadata is read to expand a $search criterion into a case insensitive regex query.</td>
105
+ </tr>
106
+ <tr>
107
+ <td>url: string</td>
108
+ <td>no</td>
109
+ <td>Declared but not read: the connection string is always built from host, port, the credentials and database.</td>
110
+ </tr>
111
+ </table>
112
+
113
+ ## 🛠️ Services & Methods
114
+
115
+ ### MongoItemRepository
116
+
117
+ Implements `IItemRepository<T>`. Inject it through the `IItemRepository` token. It maps `id` to MongoDB's `_id` on the way in and back again on the way out, and records the acting user and a timestamp under a hidden `__info` field that is stripped from everything it returns.
118
+
119
+ Methods:
120
+
121
+ <table>
122
+ <tr>
123
+ <td>create</td>
124
+ <td>Inserts one document, stamping the acting user and the date</td>
125
+ </tr>
126
+ <tr>
127
+ <td>createMany</td>
128
+ <td>Inserts many documents in one call</td>
129
+ </tr>
130
+ <tr>
131
+ <td>update</td>
132
+ <td>Replaces the whole document, keeping the creation record</td>
133
+ </tr>
134
+ <tr>
135
+ <td>updatePartial</td>
136
+ <td>Sets only the fields present on the given object</td>
137
+ </tr>
138
+ <tr>
139
+ <td>updatePartialManyByCriteria</td>
140
+ <td>Applies one partial update to every document matching a raw criteria object</td>
141
+ </tr>
142
+ <tr>
143
+ <td>updatePartialManyBySpecification</td>
144
+ <td>The same, driven by a specification</td>
145
+ </tr>
146
+ <tr>
147
+ <td>delete</td>
148
+ <td>Removes one document by its identifier</td>
149
+ </tr>
150
+ <tr>
151
+ <td>clear</td>
152
+ <td>Empties the collection</td>
153
+ </tr>
154
+ <tr>
155
+ <td>getById</td>
156
+ <td>Reads one document, with _id mapped back to id</td>
157
+ </tr>
158
+ <tr>
159
+ <td>getByCriteria</td>
160
+ <td>Reads a filtered page together with the total number of matches</td>
161
+ </tr>
162
+ <tr>
163
+ <td>getBySpecification</td>
164
+ <td>The same, from a specification</td>
165
+ </tr>
166
+ <tr>
167
+ <td>countByCriteria</td>
168
+ <td>Counts matches without loading them</td>
169
+ </tr>
170
+ <tr>
171
+ <td>countBySpecification</td>
172
+ <td>The same, from a specification</td>
173
+ </tr>
174
+ <tr>
175
+ <td>changesByCriteria</td>
176
+ <td>Watches a change stream and emits create, update and delete events</td>
177
+ </tr>
178
+ </table>
179
+
180
+ ### MongoAttachmentRepository
181
+
182
+ Implements `IAttachmentRepository<T>` on GridFS, in a bucket named by `collection`. Inject it through the `IAttachmentRepository` token.
183
+
184
+ Methods:
185
+
186
+ <table>
187
+ <tr>
188
+ <td>upload</td>
189
+ <td>Streams a file into the bucket under the given id</td>
190
+ </tr>
191
+ <tr>
192
+ <td>getInfo</td>
193
+ <td>Returns the file name, content type and length, or null when there is no such file</td>
194
+ </tr>
195
+ <tr>
196
+ <td>getStream</td>
197
+ <td>Opens a readable stream over the file, optionally over a byte range</td>
198
+ </tr>
199
+ <tr>
200
+ <td>delete</td>
201
+ <td>Removes the file from the bucket</td>
202
+ </tr>
203
+ </table>
204
+
205
+ ### MongoUnitOfWork
206
+
207
+ Implements `IUnitOfWork`. Inject it through the `IUnitOfWork` token.
208
+
209
+ Methods:
210
+
211
+ <table>
212
+ <tr>
213
+ <td>scope</td>
214
+ <td>Runs the callback inside a MongoDB transaction, committing it on success and aborting it on a throw</td>
215
+ </tr>
216
+ </table>
217
+
218
+ The callback receives an `IMongoTransaction`, an `ITransaction` whose `session` is the driver's `ClientSession`. Pass it on as `{ transaction }` to every repository call that has to take part in it.
219
+
220
+ ## 🔧 Functions
221
+
222
+ <table>
223
+ <tr>
224
+ <td>getMongoUrl(config: MongoConfig): string</td>
225
+ <td>Builds the connection string the repositories connect with</td>
226
+ </tr>
227
+ </table>
package/package.json CHANGED
@@ -1,6 +1,9 @@
1
1
  {
2
2
  "name": "@smartsoft001/mongo",
3
- "version": "2.148.0",
3
+ "version": "2.150.0",
4
+ "type": "commonjs",
5
+ "main": "./src/index.js",
6
+ "typings": "./src/index.d.ts",
4
7
  "publishConfig": {
5
8
  "access": "public"
6
9
  },
@@ -20,26 +23,11 @@
20
23
  "url": "https://github.com/emiljuchnikowski/smartsoft/issues"
21
24
  },
22
25
  "homepage": "https://github.com/emiljuchnikowski/smartsoft#readme",
23
- "dependencies": {
24
- "@angular/core": "22.1.3",
25
- "@jest/globals": "30.4.1",
26
- "@nestjs/common": "^11.1.5",
27
- "flatted": "3.4.4",
28
- "guid-typescript": "^1.0.9",
29
- "lodash": "4.18.1",
30
- "md5": "^2.3.0",
31
- "mongodb": "^7.5.0",
32
- "reflect-metadata": "^0.2.1",
33
- "rxjs": "^7.8.1",
34
- "tslib": "^2.3.0"
26
+ "peerDependencies": {
27
+ "@smartsoft001/domain-core": "2.150.0",
28
+ "@smartsoft001/models": "2.150.0",
29
+ "@smartsoft001/users": "2.150.0",
30
+ "@smartsoft001/utils": "2.150.0"
35
31
  },
36
- "overrides": {
37
- "less": "4.6.7"
38
- },
39
- "resolutions": {
40
- "paypal-rest-sdk": "1.8.1",
41
- "tslib": "^2.3.0"
42
- },
43
- "main": "./index.cjs",
44
- "type": "commonjs"
32
+ "types": "./src/index.d.ts"
45
33
  }
package/src/index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  export * from './lib/mongo.module';
2
- export * from './lib/repositories/item.repository';
3
2
  export * from './lib/mongo.config';
3
+ export * from './lib/mongo.unitofwork';
4
+ export * from './lib/mongo.utils';
5
+ export * from './lib/repositories/attachment.repository';
6
+ export * from './lib/repositories/interfaces';
7
+ export * from './lib/repositories/item.repository';
package/src/index.js ADDED
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./lib/mongo.module"), exports);
5
+ tslib_1.__exportStar(require("./lib/mongo.config"), exports);
6
+ tslib_1.__exportStar(require("./lib/mongo.unitofwork"), exports);
7
+ tslib_1.__exportStar(require("./lib/mongo.utils"), exports);
8
+ tslib_1.__exportStar(require("./lib/repositories/attachment.repository"), exports);
9
+ tslib_1.__exportStar(require("./lib/repositories/interfaces"), exports);
10
+ tslib_1.__exportStar(require("./lib/repositories/item.repository"), exports);
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/shared/mongo/src/index.ts"],"names":[],"mappings":";;;AAAA,6DAAmC;AACnC,6DAAmC;AACnC,iEAAuC;AACvC,4DAAkC;AAClC,mFAAyD;AACzD,wEAA8C;AAC9C,6EAAmD"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoConfig = void 0;
4
+ class MongoConfig {
5
+ host;
6
+ port;
7
+ database;
8
+ username;
9
+ password;
10
+ collection;
11
+ url;
12
+ type;
13
+ }
14
+ exports.MongoConfig = MongoConfig;
15
+ //# sourceMappingURL=mongo.config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo.config.js","sourceRoot":"","sources":["../../../../../../packages/shared/mongo/src/lib/mongo.config.ts"],"names":[],"mappings":";;;AAAA,MAAa,WAAW;IACtB,IAAI,CAAU;IACd,IAAI,CAAU;IACd,QAAQ,CAAS;IACjB,QAAQ,CAAU;IAClB,QAAQ,CAAU;IAClB,UAAU,CAAU;IACpB,GAAG,CAAU;IACb,IAAI,CAAO;CACZ;AATD,kCASC"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoItemRepository = exports.MongoConfig = exports.MongoModule = void 0;
4
+ const domain_core_1 = require("@smartsoft001/domain-core");
5
+ const mongo_config_1 = require("./mongo.config");
6
+ const mongo_unitofwork_1 = require("./mongo.unitofwork");
7
+ const attachment_repository_1 = require("./repositories/attachment.repository");
8
+ const item_repository_1 = require("./repositories/item.repository");
9
+ class MongoModule {
10
+ static forRoot(config) {
11
+ const providers = [
12
+ { provide: mongo_config_1.MongoConfig, useValue: config },
13
+ { provide: domain_core_1.IItemRepository, useClass: item_repository_1.MongoItemRepository },
14
+ { provide: domain_core_1.IAttachmentRepository, useClass: attachment_repository_1.MongoAttachmentRepository },
15
+ { provide: domain_core_1.IUnitOfWork, useClass: mongo_unitofwork_1.MongoUnitOfWork },
16
+ ];
17
+ return {
18
+ module: MongoModule,
19
+ providers: providers,
20
+ exports: providers,
21
+ };
22
+ }
23
+ }
24
+ exports.MongoModule = MongoModule;
25
+ var mongo_config_2 = require("./mongo.config");
26
+ Object.defineProperty(exports, "MongoConfig", { enumerable: true, get: function () { return mongo_config_2.MongoConfig; } });
27
+ var item_repository_2 = require("./repositories/item.repository");
28
+ Object.defineProperty(exports, "MongoItemRepository", { enumerable: true, get: function () { return item_repository_2.MongoItemRepository; } });
29
+ //# sourceMappingURL=mongo.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo.module.js","sourceRoot":"","sources":["../../../../../../packages/shared/mongo/src/lib/mongo.module.ts"],"names":[],"mappings":";;;AAEA,2DAImC;AAEnC,iDAA6C;AAC7C,yDAAqD;AACrD,gFAAiF;AACjF,oEAAqE;AAErE,MAAa,WAAW;IACtB,MAAM,CAAC,OAAO,CAAC,MAAmB;QAChC,MAAM,SAAS,GAAG;YAChB,EAAE,OAAO,EAAE,0BAAW,EAAE,QAAQ,EAAE,MAAM,EAAE;YAC1C,EAAE,OAAO,EAAE,6BAAe,EAAE,QAAQ,EAAE,qCAAmB,EAAE;YAC3D,EAAE,OAAO,EAAE,mCAAqB,EAAE,QAAQ,EAAE,iDAAyB,EAAE;YACvE,EAAE,OAAO,EAAE,yBAAW,EAAE,QAAQ,EAAE,kCAAe,EAAE;SACpD,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,WAAW;YACnB,SAAS,EAAE,SAAS;YACpB,OAAO,EAAE,SAAS;SACnB,CAAC;IACJ,CAAC;CACF;AAfD,kCAeC;AAED,+CAA6C;AAApC,2GAAA,WAAW,OAAA;AACpB,kEAAqE;AAA5D,sHAAA,mBAAmB,OAAA"}
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoUnitOfWork = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const mongodb_1 = require("mongodb");
7
+ const domain_core_1 = require("@smartsoft001/domain-core");
8
+ const mongo_config_1 = require("./mongo.config");
9
+ const mongo_utils_1 = require("./mongo.utils");
10
+ let MongoUnitOfWork = class MongoUnitOfWork extends domain_core_1.IUnitOfWork {
11
+ config;
12
+ constructor(config) {
13
+ super();
14
+ this.config = config;
15
+ }
16
+ async scope(definition) {
17
+ const client = await mongodb_1.MongoClient.connect(this.getUrl());
18
+ // Step 1: Start a Client Session
19
+ const session = client.startSession();
20
+ // Step 2: Optional. Define options to use for the transaction
21
+ const transactionOptions = {
22
+ readPreference: 'primary',
23
+ readConcern: { level: 'local' },
24
+ writeConcern: { w: 'majority' },
25
+ };
26
+ // Step 3: Use withTransaction to start a transaction, execute the callback, and commit (or abort on error)
27
+ // Note: The callback for withTransaction MUST be async and/or return a Promise.
28
+ let error = null;
29
+ try {
30
+ await session.withTransaction(async () => {
31
+ await definition({
32
+ session,
33
+ connection: client,
34
+ });
35
+ }, transactionOptions);
36
+ }
37
+ catch (e) {
38
+ error = e;
39
+ }
40
+ finally {
41
+ await session.endSession();
42
+ await client.close();
43
+ }
44
+ if (error)
45
+ throw error;
46
+ }
47
+ getUrl() {
48
+ return (0, mongo_utils_1.getMongoUrl)(this.config);
49
+ }
50
+ };
51
+ exports.MongoUnitOfWork = MongoUnitOfWork;
52
+ exports.MongoUnitOfWork = MongoUnitOfWork = tslib_1.__decorate([
53
+ (0, common_1.Injectable)(),
54
+ tslib_1.__metadata("design:paramtypes", [mongo_config_1.MongoConfig])
55
+ ], MongoUnitOfWork);
56
+ //# sourceMappingURL=mongo.unitofwork.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo.unitofwork.js","sourceRoot":"","sources":["../../../../../../packages/shared/mongo/src/lib/mongo.unitofwork.ts"],"names":[],"mappings":";;;;AAAA,2CAA4C;AAC5C,qCAAyE;AAEzE,2DAAsE;AAEtE,iDAA6C;AAC7C,+CAA4C;AAOrC,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,yBAAW;IAC1B;IAApB,YAAoB,MAAmB;QACrC,KAAK,EAAE,CAAC;QADU,WAAM,GAAN,MAAM,CAAa;IAEvC,CAAC;IAED,KAAK,CAAC,KAAK,CACT,UAAwD;QAExD,MAAM,MAAM,GAAG,MAAM,qBAAW,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAExD,iCAAiC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;QAEtC,8DAA8D;QAC9D,MAAM,kBAAkB,GAAuB;YAC7C,cAAc,EAAE,SAAS;YACzB,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;YAC/B,YAAY,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE;SAChC,CAAC;QAEF,2GAA2G;QAC3G,gFAAgF;QAEhF,IAAI,KAAK,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE;gBACvC,MAAM,UAAU,CAAC;oBACf,OAAO;oBACP,UAAU,EAAE,MAAM;iBACE,CAAC,CAAC;YAC1B,CAAC,EAAE,kBAAkB,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;gBAAS,CAAC;YACT,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;YAC3B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;QAED,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;IACzB,CAAC;IAEO,MAAM;QACZ,OAAO,IAAA,yBAAW,EAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;CACF,CAAA;AA5CY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;6CAEiB,0BAAW;GAD5B,eAAe,CA4C3B"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMongoUrl = getMongoUrl;
4
+ function getMongoUrl(config) {
5
+ let url;
6
+ if (config.username && config.password)
7
+ url = `mongodb://${config.username}:${config.password}@${config.host}:${config.port}`;
8
+ else
9
+ url = `mongodb://${config.host}:${config.port}`;
10
+ url = url + '?authSource=' + config.database;
11
+ if (config.host.indexOf('ondigitalocean.com') > -1) {
12
+ url = url.replace('mongodb://', 'mongodb+srv://');
13
+ url = url + '&tls=true';
14
+ }
15
+ return url;
16
+ }
17
+ //# sourceMappingURL=mongo.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mongo.utils.js","sourceRoot":"","sources":["../../../../../../packages/shared/mongo/src/lib/mongo.utils.ts"],"names":[],"mappings":";;AAEA,kCAcC;AAdD,SAAgB,WAAW,CAAC,MAAmB;IAC7C,IAAI,GAAG,CAAC;IACR,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ;QACpC,GAAG,GAAG,aAAa,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;;QACnF,GAAG,GAAG,aAAa,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;IAErD,GAAG,GAAG,GAAG,GAAG,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC;IAE7C,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAClD,GAAG,GAAG,GAAG,GAAG,WAAW,CAAC;IAC1B,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MongoAttachmentRepository = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@nestjs/common");
6
+ const mongodb_1 = require("mongodb");
7
+ const mongo = tslib_1.__importStar(require("mongodb"));
8
+ const domain_core_1 = require("@smartsoft001/domain-core");
9
+ const mongo_config_1 = require("../mongo.config");
10
+ const mongo_utils_1 = require("../mongo.utils");
11
+ let MongoAttachmentRepository = class MongoAttachmentRepository extends domain_core_1.IAttachmentRepository {
12
+ config;
13
+ constructor(config) {
14
+ super();
15
+ this.config = config;
16
+ }
17
+ async upload(data, options) {
18
+ const client = await mongodb_1.MongoClient.connect(this.getUrl());
19
+ return await new Promise((res, rej) => {
20
+ const db = client.db(this.config.database);
21
+ const bucket = new mongo.GridFSBucket(db, {
22
+ bucketName: this.config.collection,
23
+ });
24
+ const writeStream = bucket.openUploadStreamWithId(data.id, data.fileName, {
25
+ metadata: { contentType: data.mimeType },
26
+ });
27
+ if (options?.streamCallback)
28
+ options.streamCallback(writeStream);
29
+ data.stream.pipe(writeStream);
30
+ writeStream.on('error', (error) => {
31
+ rej(error);
32
+ });
33
+ writeStream.on('finish', () => {
34
+ res();
35
+ });
36
+ });
37
+ }
38
+ async getInfo(id) {
39
+ const client = await mongodb_1.MongoClient.connect(this.getUrl());
40
+ const db = client.db(this.config.database);
41
+ const bucket = new mongo.GridFSBucket(db, {
42
+ bucketName: this.config.collection,
43
+ });
44
+ const items = await bucket
45
+ .find({
46
+ _id: id,
47
+ })
48
+ .toArray();
49
+ if (!items || items.length === 0)
50
+ return null;
51
+ return {
52
+ fileName: items[0].filename,
53
+ // mongodb 7 removed the deprecated top-level contentType - files written
54
+ // by older driver versions still carry it, so fall back to it
55
+ contentType: items[0].metadata?.['contentType'] ??
56
+ items[0].contentType,
57
+ length: items[0].length,
58
+ };
59
+ }
60
+ async getStream(id, options) {
61
+ const client = await mongodb_1.MongoClient.connect(this.getUrl());
62
+ const db = client.db(this.config.database);
63
+ const bucket = new mongo.GridFSBucket(db, {
64
+ bucketName: this.config.collection,
65
+ });
66
+ return bucket.openDownloadStream(id, options);
67
+ }
68
+ async delete(id) {
69
+ const client = await mongodb_1.MongoClient.connect(this.getUrl());
70
+ const db = client.db(this.config.database);
71
+ const bucket = new mongo.GridFSBucket(db, {
72
+ bucketName: this.config.collection,
73
+ });
74
+ await bucket.delete(id);
75
+ await client.close();
76
+ }
77
+ getUrl() {
78
+ return (0, mongo_utils_1.getMongoUrl)(this.config);
79
+ }
80
+ };
81
+ exports.MongoAttachmentRepository = MongoAttachmentRepository;
82
+ exports.MongoAttachmentRepository = MongoAttachmentRepository = tslib_1.__decorate([
83
+ (0, common_1.Injectable)(),
84
+ tslib_1.__metadata("design:paramtypes", [mongo_config_1.MongoConfig])
85
+ ], MongoAttachmentRepository);
86
+ //# sourceMappingURL=attachment.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment.repository.js","sourceRoot":"","sources":["../../../../../../../packages/shared/mongo/src/lib/repositories/attachment.repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=interfaces.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.js","sourceRoot":"","sources":["../../../../../../../packages/shared/mongo/src/lib/repositories/interfaces.ts"],"names":[],"mappings":""}