@yandjin-mikro-orm/mongodb 6.1.4-rc-sti-changes-1
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/LICENSE +21 -0
- package/MongoConnection.d.ts +51 -0
- package/MongoConnection.js +368 -0
- package/MongoDriver.d.ts +29 -0
- package/MongoDriver.js +315 -0
- package/MongoEntityManager.d.ts +26 -0
- package/MongoEntityManager.js +38 -0
- package/MongoEntityRepository.d.ts +16 -0
- package/MongoEntityRepository.js +27 -0
- package/MongoExceptionConverter.d.ts +7 -0
- package/MongoExceptionConverter.js +20 -0
- package/MongoMikroORM.d.ts +19 -0
- package/MongoMikroORM.js +29 -0
- package/MongoPlatform.d.ts +28 -0
- package/MongoPlatform.js +82 -0
- package/MongoSchemaGenerator.d.ts +32 -0
- package/MongoSchemaGenerator.js +215 -0
- package/README.md +383 -0
- package/index.d.ts +11 -0
- package/index.js +34 -0
- package/index.mjs +199 -0
- package/package.json +70 -0
package/MongoDriver.js
ADDED
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoDriver = void 0;
|
|
4
|
+
const bson_1 = require("bson");
|
|
5
|
+
const core_1 = require("@yandjin-mikro-orm/core");
|
|
6
|
+
const MongoConnection_1 = require("./MongoConnection");
|
|
7
|
+
const MongoPlatform_1 = require("./MongoPlatform");
|
|
8
|
+
const MongoEntityManager_1 = require("./MongoEntityManager");
|
|
9
|
+
class MongoDriver extends core_1.DatabaseDriver {
|
|
10
|
+
[core_1.EntityManagerType];
|
|
11
|
+
connection = new MongoConnection_1.MongoConnection(this.config);
|
|
12
|
+
platform = new MongoPlatform_1.MongoPlatform();
|
|
13
|
+
constructor(config) {
|
|
14
|
+
super(config, ["mongodb"]);
|
|
15
|
+
}
|
|
16
|
+
createEntityManager(useContext) {
|
|
17
|
+
const EntityManagerClass = this.config.get("entityManager", MongoEntityManager_1.MongoEntityManager);
|
|
18
|
+
return new EntityManagerClass(this.config, this, this.metadata, useContext);
|
|
19
|
+
}
|
|
20
|
+
async find(entityName, where, options = {}) {
|
|
21
|
+
if (this.metadata.find(entityName)?.virtual) {
|
|
22
|
+
return this.findVirtual(entityName, where, options);
|
|
23
|
+
}
|
|
24
|
+
const { first, last, before, after } = options;
|
|
25
|
+
const fields = this.buildFields(entityName, options.populate || [], options.fields, options.exclude);
|
|
26
|
+
where = this.renameFields(entityName, where, true);
|
|
27
|
+
const isCursorPagination = [first, last, before, after].some((v) => v != null);
|
|
28
|
+
if (isCursorPagination) {
|
|
29
|
+
const andWhere = (cond1, cond2) => {
|
|
30
|
+
if (core_1.Utils.isEmpty(cond1)) {
|
|
31
|
+
return cond2;
|
|
32
|
+
}
|
|
33
|
+
if (core_1.Utils.isEmpty(cond2)) {
|
|
34
|
+
return cond1;
|
|
35
|
+
}
|
|
36
|
+
return { $and: [cond1, cond2] };
|
|
37
|
+
};
|
|
38
|
+
const meta = this.metadata.find(entityName);
|
|
39
|
+
const { orderBy: newOrderBy, where: newWhere } = this.processCursorOptions(meta, options, options.orderBy);
|
|
40
|
+
const newWhereConverted = this.renameFields(entityName, newWhere, true);
|
|
41
|
+
const orderBy = core_1.Utils.asArray(newOrderBy).map((order) => this.renameFields(entityName, order));
|
|
42
|
+
const res = await this.rethrow(this.getConnection("read").find(entityName, andWhere(where, newWhereConverted), orderBy, options.limit, options.offset, fields, options.ctx, options.logging));
|
|
43
|
+
if (isCursorPagination && !first && !!last) {
|
|
44
|
+
res.reverse();
|
|
45
|
+
}
|
|
46
|
+
return res.map((r) => this.mapResult(r, this.metadata.find(entityName)));
|
|
47
|
+
}
|
|
48
|
+
const orderBy = core_1.Utils.asArray(options.orderBy).map((orderBy) => this.renameFields(entityName, orderBy, false));
|
|
49
|
+
const res = await this.rethrow(this.getConnection("read").find(entityName, where, orderBy, options.limit, options.offset, fields, options.ctx));
|
|
50
|
+
return res.map((r) => this.mapResult(r, this.metadata.find(entityName)));
|
|
51
|
+
}
|
|
52
|
+
async findOne(entityName, where, options = { populate: [], orderBy: {} }) {
|
|
53
|
+
if (this.metadata.find(entityName)?.virtual) {
|
|
54
|
+
const [item] = await this.findVirtual(entityName, where, options);
|
|
55
|
+
/* istanbul ignore next */
|
|
56
|
+
return item ?? null;
|
|
57
|
+
}
|
|
58
|
+
if (core_1.Utils.isPrimaryKey(where)) {
|
|
59
|
+
where = this.buildFilterById(entityName, where);
|
|
60
|
+
}
|
|
61
|
+
const fields = this.buildFields(entityName, options.populate || [], options.fields, options.exclude);
|
|
62
|
+
where = this.renameFields(entityName, where, true);
|
|
63
|
+
const orderBy = core_1.Utils.asArray(options.orderBy).map((orderBy) => this.renameFields(entityName, orderBy, false));
|
|
64
|
+
const res = await this.rethrow(this.getConnection("read").find(entityName, where, orderBy, 1, undefined, fields, options.ctx, options.logging));
|
|
65
|
+
return this.mapResult(res[0], this.metadata.find(entityName));
|
|
66
|
+
}
|
|
67
|
+
async findVirtual(entityName, where, options) {
|
|
68
|
+
const meta = this.metadata.find(entityName);
|
|
69
|
+
if (meta.expression instanceof Function) {
|
|
70
|
+
const em = this.createEntityManager();
|
|
71
|
+
return meta.expression(em, where, options);
|
|
72
|
+
}
|
|
73
|
+
/* istanbul ignore next */
|
|
74
|
+
return super.findVirtual(entityName, where, options);
|
|
75
|
+
}
|
|
76
|
+
async count(entityName, where, options = {}, ctx) {
|
|
77
|
+
/* istanbul ignore next */
|
|
78
|
+
if (this.metadata.find(entityName)?.virtual) {
|
|
79
|
+
return this.countVirtual(entityName, where, options);
|
|
80
|
+
}
|
|
81
|
+
where = this.renameFields(entityName, where, true);
|
|
82
|
+
return this.rethrow(this.getConnection("read").countDocuments(entityName, where, ctx));
|
|
83
|
+
}
|
|
84
|
+
async nativeInsert(entityName, data, options = {}) {
|
|
85
|
+
data = this.renameFields(entityName, data);
|
|
86
|
+
return this.rethrow(this.getConnection("write").insertOne(entityName, data, options.ctx));
|
|
87
|
+
}
|
|
88
|
+
async nativeInsertMany(entityName, data, options = {}) {
|
|
89
|
+
data = data.map((d) => this.renameFields(entityName, d));
|
|
90
|
+
const meta = this.metadata.find(entityName);
|
|
91
|
+
/* istanbul ignore next */
|
|
92
|
+
const pk = meta?.getPrimaryProps()[0].fieldNames[0] ?? "_id";
|
|
93
|
+
const res = await this.rethrow(this.getConnection("write").insertMany(entityName, data, options.ctx));
|
|
94
|
+
res.rows = res.insertedIds.map((id) => ({ [pk]: id }));
|
|
95
|
+
return res;
|
|
96
|
+
}
|
|
97
|
+
async nativeUpdate(entityName, where, data, options = {}) {
|
|
98
|
+
if (core_1.Utils.isPrimaryKey(where)) {
|
|
99
|
+
where = this.buildFilterById(entityName, where);
|
|
100
|
+
}
|
|
101
|
+
where = this.renameFields(entityName, where, true);
|
|
102
|
+
data = this.renameFields(entityName, data);
|
|
103
|
+
options = { ...options };
|
|
104
|
+
const meta = this.metadata.find(entityName);
|
|
105
|
+
/* istanbul ignore next */
|
|
106
|
+
const rename = (field) => meta
|
|
107
|
+
? (meta.properties[field]?.fieldNames[0] ??
|
|
108
|
+
field)
|
|
109
|
+
: field;
|
|
110
|
+
if (options.onConflictFields) {
|
|
111
|
+
options.onConflictFields = options.onConflictFields.map(rename);
|
|
112
|
+
}
|
|
113
|
+
if (options.onConflictMergeFields) {
|
|
114
|
+
options.onConflictMergeFields = options.onConflictMergeFields.map(rename);
|
|
115
|
+
}
|
|
116
|
+
if (options.onConflictExcludeFields) {
|
|
117
|
+
options.onConflictExcludeFields =
|
|
118
|
+
options.onConflictExcludeFields.map(rename);
|
|
119
|
+
}
|
|
120
|
+
return this.rethrow(this.getConnection("write").updateMany(entityName, where, data, options.ctx, options.upsert, options));
|
|
121
|
+
}
|
|
122
|
+
async nativeUpdateMany(entityName, where, data, options = {}) {
|
|
123
|
+
where = where.map((row) => {
|
|
124
|
+
if (core_1.Utils.isPlainObject(row)) {
|
|
125
|
+
return this.renameFields(entityName, row, true);
|
|
126
|
+
}
|
|
127
|
+
return row;
|
|
128
|
+
});
|
|
129
|
+
data = data.map((row) => this.renameFields(entityName, row));
|
|
130
|
+
options = { ...options };
|
|
131
|
+
const meta = this.metadata.find(entityName);
|
|
132
|
+
/* istanbul ignore next */
|
|
133
|
+
const rename = (field) => meta
|
|
134
|
+
? (meta.properties[field]?.fieldNames[0] ??
|
|
135
|
+
field)
|
|
136
|
+
: field;
|
|
137
|
+
if (options.onConflictFields) {
|
|
138
|
+
options.onConflictFields = options.onConflictFields.map(rename);
|
|
139
|
+
}
|
|
140
|
+
if (options.onConflictMergeFields) {
|
|
141
|
+
options.onConflictMergeFields = options.onConflictMergeFields.map(rename);
|
|
142
|
+
}
|
|
143
|
+
if (options.onConflictExcludeFields) {
|
|
144
|
+
options.onConflictExcludeFields =
|
|
145
|
+
options.onConflictExcludeFields.map(rename);
|
|
146
|
+
}
|
|
147
|
+
return this.rethrow(this.getConnection("write").bulkUpdateMany(entityName, where, data, options.ctx, options.upsert, options));
|
|
148
|
+
}
|
|
149
|
+
async nativeDelete(entityName, where, options = {}) {
|
|
150
|
+
if (core_1.Utils.isPrimaryKey(where)) {
|
|
151
|
+
where = this.buildFilterById(entityName, where);
|
|
152
|
+
}
|
|
153
|
+
where = this.renameFields(entityName, where, true);
|
|
154
|
+
return this.rethrow(this.getConnection("write").deleteMany(entityName, where, options.ctx));
|
|
155
|
+
}
|
|
156
|
+
async aggregate(entityName, pipeline, ctx) {
|
|
157
|
+
return this.rethrow(this.getConnection("read").aggregate(entityName, pipeline, ctx));
|
|
158
|
+
}
|
|
159
|
+
getPlatform() {
|
|
160
|
+
return this.platform;
|
|
161
|
+
}
|
|
162
|
+
renameFields(entityName, data, where = false, object) {
|
|
163
|
+
// copy to new variable to prevent changing the T type or doing as unknown casts
|
|
164
|
+
const copiedData = Object.assign({}, data); // copy first
|
|
165
|
+
const meta = this.metadata.find(entityName);
|
|
166
|
+
if (meta?.serializedPrimaryKey &&
|
|
167
|
+
!meta.embeddable &&
|
|
168
|
+
meta.serializedPrimaryKey !== meta.primaryKeys[0]) {
|
|
169
|
+
core_1.Utils.renameKey(copiedData, meta.serializedPrimaryKey, meta.primaryKeys[0]);
|
|
170
|
+
}
|
|
171
|
+
if (meta && !meta.embeddable) {
|
|
172
|
+
this.inlineEmbeddables(meta, copiedData, where);
|
|
173
|
+
}
|
|
174
|
+
// If we had a query with $fulltext and some filter we end up with $and with $fulltext in it.
|
|
175
|
+
// We will try to move $fulltext to top level.
|
|
176
|
+
if (copiedData.$and) {
|
|
177
|
+
for (let i = 0; i < copiedData.$and.length; i++) {
|
|
178
|
+
const and = copiedData.$and[i];
|
|
179
|
+
if ("$fulltext" in and) {
|
|
180
|
+
/* istanbul ignore next */
|
|
181
|
+
if ("$fulltext" in copiedData) {
|
|
182
|
+
throw new Error("Cannot merge multiple $fulltext conditions to top level of the query object.");
|
|
183
|
+
}
|
|
184
|
+
copiedData.$fulltext = and.$fulltext;
|
|
185
|
+
delete and.$fulltext;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// move search terms from data['$fulltext'] to mongo's structure: data['$text']['search']
|
|
190
|
+
if ("$fulltext" in copiedData) {
|
|
191
|
+
copiedData.$text = { $search: copiedData.$fulltext };
|
|
192
|
+
delete copiedData.$fulltext;
|
|
193
|
+
}
|
|
194
|
+
// mongo only allows the $text operator in the root of the object and will
|
|
195
|
+
// search all documents where the field has a text index.
|
|
196
|
+
if (core_1.Utils.hasNestedKey(copiedData, "$fulltext")) {
|
|
197
|
+
throw new Error("Full text search is only supported on the top level of the query object.");
|
|
198
|
+
}
|
|
199
|
+
core_1.Utils.keys(copiedData).forEach((k) => {
|
|
200
|
+
if (core_1.Utils.isGroupOperator(k)) {
|
|
201
|
+
/* istanbul ignore else */
|
|
202
|
+
if (Array.isArray(copiedData[k])) {
|
|
203
|
+
copiedData[k] = copiedData[k].map((v) => this.renameFields(entityName, v));
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
copiedData[k] = this.renameFields(entityName, copiedData[k]);
|
|
207
|
+
}
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
if (meta?.properties[k]) {
|
|
211
|
+
const prop = meta.properties[k];
|
|
212
|
+
let isObjectId = false;
|
|
213
|
+
if (prop.kind === core_1.ReferenceKind.SCALAR) {
|
|
214
|
+
isObjectId = prop.type.toLowerCase() === "objectid";
|
|
215
|
+
}
|
|
216
|
+
else if (prop.kind === core_1.ReferenceKind.EMBEDDED) {
|
|
217
|
+
if (copiedData[prop.name] == null) {
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
if (prop.array && Array.isArray(copiedData[prop.name])) {
|
|
221
|
+
copiedData[prop.name] = copiedData[prop.name].map((item) => this.renameFields(prop.type, item, where, true));
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
copiedData[prop.name] = this.renameFields(prop.type, copiedData[prop.name], where, prop.object || object);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
const meta2 = this.metadata.find(prop.type);
|
|
229
|
+
const pk = meta2.properties[meta2.primaryKeys[0]];
|
|
230
|
+
isObjectId = pk.type.toLowerCase() === "objectid";
|
|
231
|
+
}
|
|
232
|
+
if (isObjectId) {
|
|
233
|
+
copiedData[k] = this.convertObjectIds(copiedData[k]);
|
|
234
|
+
}
|
|
235
|
+
if (prop.fieldNames) {
|
|
236
|
+
core_1.Utils.renameKey(copiedData, k, prop.fieldNames[0]);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (core_1.Utils.isPlainObject(copiedData[k]) && "$re" in copiedData[k]) {
|
|
240
|
+
copiedData[k] = new RegExp(copiedData[k].$re);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
return copiedData;
|
|
244
|
+
}
|
|
245
|
+
convertObjectIds(data) {
|
|
246
|
+
if (data instanceof bson_1.ObjectId) {
|
|
247
|
+
return data;
|
|
248
|
+
}
|
|
249
|
+
if (core_1.Utils.isString(data) && data.match(/^[0-9a-f]{24}$/i)) {
|
|
250
|
+
return new bson_1.ObjectId(data);
|
|
251
|
+
}
|
|
252
|
+
if (Array.isArray(data)) {
|
|
253
|
+
return data.map((item) => this.convertObjectIds(item));
|
|
254
|
+
}
|
|
255
|
+
if (core_1.Utils.isObject(data)) {
|
|
256
|
+
Object.keys(data).forEach((k) => {
|
|
257
|
+
data[k] = this.convertObjectIds(data[k]);
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return data;
|
|
261
|
+
}
|
|
262
|
+
buildFilterById(entityName, id) {
|
|
263
|
+
const meta = this.metadata.find(entityName);
|
|
264
|
+
if (meta.properties[meta.primaryKeys[0]].type.toLowerCase() === "objectid") {
|
|
265
|
+
return { _id: new bson_1.ObjectId(id) };
|
|
266
|
+
}
|
|
267
|
+
return { _id: id };
|
|
268
|
+
}
|
|
269
|
+
buildFields(entityName, populate, fields, exclude) {
|
|
270
|
+
const meta = this.metadata.find(entityName);
|
|
271
|
+
if (!meta) {
|
|
272
|
+
return fields;
|
|
273
|
+
}
|
|
274
|
+
const lazyProps = meta.props.filter((prop) => prop.lazy && !populate.some((p) => p.field === prop.name || p.all));
|
|
275
|
+
const ret = [];
|
|
276
|
+
if (fields) {
|
|
277
|
+
for (let field of fields) {
|
|
278
|
+
/* istanbul ignore next */
|
|
279
|
+
if (core_1.Utils.isPlainObject(field)) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (field.toString().includes(".")) {
|
|
283
|
+
field = field
|
|
284
|
+
.toString()
|
|
285
|
+
.substring(0, field.toString().indexOf("."));
|
|
286
|
+
}
|
|
287
|
+
let prop = meta.properties[field];
|
|
288
|
+
/* istanbul ignore else */
|
|
289
|
+
if (prop) {
|
|
290
|
+
if (!prop.fieldNames) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
prop = prop.serializedPrimaryKey ? meta.getPrimaryProps()[0] : prop;
|
|
294
|
+
ret.push(prop.fieldNames[0]);
|
|
295
|
+
}
|
|
296
|
+
else if (field === "*") {
|
|
297
|
+
const props = meta.props.filter((prop) => this.platform.shouldHaveColumn(prop, populate));
|
|
298
|
+
ret.push(...core_1.Utils.flatten(props
|
|
299
|
+
.filter((p) => !lazyProps.includes(p))
|
|
300
|
+
.map((p) => p.fieldNames)));
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
ret.push(field);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
ret.unshift(...meta.primaryKeys.filter((pk) => !fields.includes(pk)));
|
|
307
|
+
}
|
|
308
|
+
else if (!core_1.Utils.isEmpty(exclude) || lazyProps.some((p) => !p.formula)) {
|
|
309
|
+
const props = meta.props.filter((prop) => this.platform.shouldHaveColumn(prop, populate, exclude));
|
|
310
|
+
ret.push(...core_1.Utils.flatten(props.filter((p) => !lazyProps.includes(p)).map((p) => p.fieldNames)));
|
|
311
|
+
}
|
|
312
|
+
return ret.length > 0 ? ret : undefined;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
exports.MongoDriver = MongoDriver;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { EntityManager, type EntityName, type EntityRepository, type GetRepository, type TransactionOptions, type EntityManagerType } from "@yandjin-mikro-orm/core";
|
|
2
|
+
import type { Collection, Document, TransactionOptions as MongoTransactionOptions } from "mongodb";
|
|
3
|
+
import type { MongoDriver } from "./MongoDriver";
|
|
4
|
+
import type { MongoEntityRepository } from "./MongoEntityRepository";
|
|
5
|
+
/**
|
|
6
|
+
* @inheritDoc
|
|
7
|
+
*/
|
|
8
|
+
export declare class MongoEntityManager<Driver extends MongoDriver = MongoDriver> extends EntityManager<Driver> {
|
|
9
|
+
/**
|
|
10
|
+
* Shortcut to driver's aggregate method. Available in MongoDriver only.
|
|
11
|
+
*/
|
|
12
|
+
aggregate(entityName: EntityName<any>, pipeline: any[]): Promise<any[]>;
|
|
13
|
+
getCollection<T extends Document>(entityName: EntityName<T>): Collection<T>;
|
|
14
|
+
/**
|
|
15
|
+
* @inheritDoc
|
|
16
|
+
*/
|
|
17
|
+
getRepository<T extends object, U extends EntityRepository<T> = MongoEntityRepository<T>>(entityName: EntityName<T>): GetRepository<T, U>;
|
|
18
|
+
/**
|
|
19
|
+
* @inheritDoc
|
|
20
|
+
*/
|
|
21
|
+
begin(options?: Omit<TransactionOptions, "ignoreNestedTransactions"> & MongoTransactionOptions): Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* @inheritDoc
|
|
24
|
+
*/
|
|
25
|
+
transactional<T>(cb: (em: Driver[typeof EntityManagerType]) => Promise<T>, options?: TransactionOptions & MongoTransactionOptions): Promise<T>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoEntityManager = void 0;
|
|
4
|
+
const core_1 = require("@yandjin-mikro-orm/core");
|
|
5
|
+
/**
|
|
6
|
+
* @inheritDoc
|
|
7
|
+
*/
|
|
8
|
+
class MongoEntityManager extends core_1.EntityManager {
|
|
9
|
+
/**
|
|
10
|
+
* Shortcut to driver's aggregate method. Available in MongoDriver only.
|
|
11
|
+
*/
|
|
12
|
+
async aggregate(entityName, pipeline) {
|
|
13
|
+
entityName = core_1.Utils.className(entityName);
|
|
14
|
+
return this.getDriver().aggregate(entityName, pipeline);
|
|
15
|
+
}
|
|
16
|
+
getCollection(entityName) {
|
|
17
|
+
return this.getConnection().getCollection(entityName);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @inheritDoc
|
|
21
|
+
*/
|
|
22
|
+
getRepository(entityName) {
|
|
23
|
+
return super.getRepository(entityName);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @inheritDoc
|
|
27
|
+
*/
|
|
28
|
+
async begin(options = {}) {
|
|
29
|
+
return super.begin(options);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* @inheritDoc
|
|
33
|
+
*/
|
|
34
|
+
async transactional(cb, options = {}) {
|
|
35
|
+
return super.transactional(cb, options);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.MongoEntityManager = MongoEntityManager;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { EntityRepository, type EntityName } from "@yandjin-mikro-orm/core";
|
|
2
|
+
import type { Collection } from "mongodb";
|
|
3
|
+
import type { MongoEntityManager } from "./MongoEntityManager";
|
|
4
|
+
export declare class MongoEntityRepository<T extends object> extends EntityRepository<T> {
|
|
5
|
+
protected readonly em: MongoEntityManager;
|
|
6
|
+
constructor(em: MongoEntityManager, entityName: EntityName<T>);
|
|
7
|
+
/**
|
|
8
|
+
* Shortcut to driver's aggregate method. Available in MongoDriver only.
|
|
9
|
+
*/
|
|
10
|
+
aggregate(pipeline: any[]): Promise<any[]>;
|
|
11
|
+
getCollection(): Collection<T>;
|
|
12
|
+
/**
|
|
13
|
+
* @inheritDoc
|
|
14
|
+
*/
|
|
15
|
+
getEntityManager(): MongoEntityManager;
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoEntityRepository = void 0;
|
|
4
|
+
const core_1 = require("@yandjin-mikro-orm/core");
|
|
5
|
+
class MongoEntityRepository extends core_1.EntityRepository {
|
|
6
|
+
em;
|
|
7
|
+
constructor(em, entityName) {
|
|
8
|
+
super(em, entityName);
|
|
9
|
+
this.em = em;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Shortcut to driver's aggregate method. Available in MongoDriver only.
|
|
13
|
+
*/
|
|
14
|
+
async aggregate(pipeline) {
|
|
15
|
+
return this.getEntityManager().aggregate(this.entityName, pipeline);
|
|
16
|
+
}
|
|
17
|
+
getCollection() {
|
|
18
|
+
return this.getEntityManager().getCollection(this.entityName);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @inheritDoc
|
|
22
|
+
*/
|
|
23
|
+
getEntityManager() {
|
|
24
|
+
return this.em;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.MongoEntityRepository = MongoEntityRepository;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ExceptionConverter, type Dictionary, type DriverException } from "@yandjin-mikro-orm/core";
|
|
2
|
+
export declare class MongoExceptionConverter extends ExceptionConverter {
|
|
3
|
+
/**
|
|
4
|
+
* @link https://gist.github.com/rluvaton/a97a8da46ab6541a3e5702e83b9d357b
|
|
5
|
+
*/
|
|
6
|
+
convertException(exception: Error & Dictionary): DriverException;
|
|
7
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoExceptionConverter = void 0;
|
|
4
|
+
const core_1 = require("@yandjin-mikro-orm/core");
|
|
5
|
+
class MongoExceptionConverter extends core_1.ExceptionConverter {
|
|
6
|
+
/* istanbul ignore next */
|
|
7
|
+
/**
|
|
8
|
+
* @link https://gist.github.com/rluvaton/a97a8da46ab6541a3e5702e83b9d357b
|
|
9
|
+
*/
|
|
10
|
+
convertException(exception) {
|
|
11
|
+
switch (exception.code) {
|
|
12
|
+
case 48:
|
|
13
|
+
return new core_1.TableExistsException(exception);
|
|
14
|
+
case 11000:
|
|
15
|
+
return new core_1.UniqueConstraintViolationException(exception);
|
|
16
|
+
}
|
|
17
|
+
return super.convertException(exception);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.MongoExceptionConverter = MongoExceptionConverter;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { MikroORM, type Options, type IDatabaseDriver, type EntityManager, type EntityManagerType } from "@yandjin-mikro-orm/core";
|
|
2
|
+
import { MongoDriver } from "./MongoDriver";
|
|
3
|
+
import type { MongoEntityManager } from "./MongoEntityManager";
|
|
4
|
+
/**
|
|
5
|
+
* @inheritDoc
|
|
6
|
+
*/
|
|
7
|
+
export declare class MongoMikroORM<EM extends EntityManager = MongoEntityManager> extends MikroORM<MongoDriver, EM> {
|
|
8
|
+
private static DRIVER;
|
|
9
|
+
/**
|
|
10
|
+
* @inheritDoc
|
|
11
|
+
*/
|
|
12
|
+
static init<D extends IDatabaseDriver = MongoDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options?: Options<D, EM>): Promise<MikroORM<D, EM>>;
|
|
13
|
+
/**
|
|
14
|
+
* @inheritDoc
|
|
15
|
+
*/
|
|
16
|
+
static initSync<D extends IDatabaseDriver = MongoDriver, EM extends EntityManager = D[typeof EntityManagerType] & EntityManager>(options: Options<D, EM>): MikroORM<D, EM>;
|
|
17
|
+
}
|
|
18
|
+
export type MongoOptions = Options<MongoDriver>;
|
|
19
|
+
export declare function defineMongoConfig(options: MongoOptions): Options<MongoDriver, MongoEntityManager<MongoDriver> & EntityManager<IDatabaseDriver<import("@yandjin-mikro-orm/core").Connection>>>;
|
package/MongoMikroORM.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineMongoConfig = exports.MongoMikroORM = void 0;
|
|
4
|
+
const core_1 = require("@yandjin-mikro-orm/core");
|
|
5
|
+
const MongoDriver_1 = require("./MongoDriver");
|
|
6
|
+
/**
|
|
7
|
+
* @inheritDoc
|
|
8
|
+
*/
|
|
9
|
+
class MongoMikroORM extends core_1.MikroORM {
|
|
10
|
+
static DRIVER = MongoDriver_1.MongoDriver;
|
|
11
|
+
/**
|
|
12
|
+
* @inheritDoc
|
|
13
|
+
*/
|
|
14
|
+
static async init(options) {
|
|
15
|
+
return super.init(options);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @inheritDoc
|
|
19
|
+
*/
|
|
20
|
+
static initSync(options) {
|
|
21
|
+
return super.initSync(options);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.MongoMikroORM = MongoMikroORM;
|
|
25
|
+
/* istanbul ignore next */
|
|
26
|
+
function defineMongoConfig(options) {
|
|
27
|
+
return (0, core_1.defineConfig)({ driver: MongoDriver_1.MongoDriver, ...options });
|
|
28
|
+
}
|
|
29
|
+
exports.defineMongoConfig = defineMongoConfig;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ObjectId } from "bson";
|
|
2
|
+
import { Platform, type IPrimaryKey, type Primary, type NamingStrategy, type Constructor, type EntityRepository, type EntityProperty, type PopulateOptions, type EntityMetadata, type IDatabaseDriver, type EntityManager, type Configuration, type MikroORM } from "@yandjin-mikro-orm/core";
|
|
3
|
+
import { MongoExceptionConverter } from "./MongoExceptionConverter";
|
|
4
|
+
import { MongoSchemaGenerator } from "./MongoSchemaGenerator";
|
|
5
|
+
export declare class MongoPlatform extends Platform {
|
|
6
|
+
protected readonly exceptionConverter: MongoExceptionConverter;
|
|
7
|
+
setConfig(config: Configuration): void;
|
|
8
|
+
getNamingStrategy(): {
|
|
9
|
+
new (): NamingStrategy;
|
|
10
|
+
};
|
|
11
|
+
getRepositoryClass<T extends object>(): Constructor<EntityRepository<T>>;
|
|
12
|
+
/** @inheritDoc */
|
|
13
|
+
lookupExtensions(orm: MikroORM): void;
|
|
14
|
+
getSchemaGenerator(driver: IDatabaseDriver, em?: EntityManager): MongoSchemaGenerator;
|
|
15
|
+
normalizePrimaryKey<T extends number | string = number | string>(data: Primary<T> | IPrimaryKey | ObjectId): T;
|
|
16
|
+
denormalizePrimaryKey(data: number | string): IPrimaryKey;
|
|
17
|
+
getSerializedPrimaryKeyField(field: string): string;
|
|
18
|
+
usesDifferentSerializedPrimaryKey(): boolean;
|
|
19
|
+
usesImplicitTransactions(): boolean;
|
|
20
|
+
convertsJsonAutomatically(): boolean;
|
|
21
|
+
convertJsonToDatabaseValue(value: unknown): unknown;
|
|
22
|
+
convertJsonToJSValue(value: unknown): unknown;
|
|
23
|
+
marshallArray(values: string[]): string;
|
|
24
|
+
cloneEmbeddable<T>(data: T): T;
|
|
25
|
+
shouldHaveColumn<T>(prop: EntityProperty<T>, populate: PopulateOptions<T>[], exclude?: string[]): boolean;
|
|
26
|
+
validateMetadata(meta: EntityMetadata): void;
|
|
27
|
+
isAllowedTopLevelOperator(operator: string): boolean;
|
|
28
|
+
}
|
package/MongoPlatform.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MongoPlatform = void 0;
|
|
4
|
+
const bson_1 = require("bson");
|
|
5
|
+
const core_1 = require("@yandjin-mikro-orm/core");
|
|
6
|
+
const MongoExceptionConverter_1 = require("./MongoExceptionConverter");
|
|
7
|
+
const MongoEntityRepository_1 = require("./MongoEntityRepository");
|
|
8
|
+
const MongoSchemaGenerator_1 = require("./MongoSchemaGenerator");
|
|
9
|
+
class MongoPlatform extends core_1.Platform {
|
|
10
|
+
exceptionConverter = new MongoExceptionConverter_1.MongoExceptionConverter();
|
|
11
|
+
setConfig(config) {
|
|
12
|
+
config.set("autoJoinOneToOneOwner", false);
|
|
13
|
+
config.set("loadStrategy", "select-in");
|
|
14
|
+
config.get("discovery").inferDefaultValues = false;
|
|
15
|
+
super.setConfig(config);
|
|
16
|
+
}
|
|
17
|
+
getNamingStrategy() {
|
|
18
|
+
return core_1.MongoNamingStrategy;
|
|
19
|
+
}
|
|
20
|
+
getRepositoryClass() {
|
|
21
|
+
return MongoEntityRepository_1.MongoEntityRepository;
|
|
22
|
+
}
|
|
23
|
+
/** @inheritDoc */
|
|
24
|
+
lookupExtensions(orm) {
|
|
25
|
+
MongoSchemaGenerator_1.MongoSchemaGenerator.register(orm);
|
|
26
|
+
}
|
|
27
|
+
/* istanbul ignore next: kept for type inference only */
|
|
28
|
+
getSchemaGenerator(driver, em) {
|
|
29
|
+
return new MongoSchemaGenerator_1.MongoSchemaGenerator(em ?? driver);
|
|
30
|
+
}
|
|
31
|
+
normalizePrimaryKey(data) {
|
|
32
|
+
if (data instanceof bson_1.ObjectId) {
|
|
33
|
+
return data.toHexString();
|
|
34
|
+
}
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
denormalizePrimaryKey(data) {
|
|
38
|
+
return new bson_1.ObjectId(data);
|
|
39
|
+
}
|
|
40
|
+
getSerializedPrimaryKeyField(field) {
|
|
41
|
+
return "id";
|
|
42
|
+
}
|
|
43
|
+
usesDifferentSerializedPrimaryKey() {
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
usesImplicitTransactions() {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
convertsJsonAutomatically() {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
convertJsonToDatabaseValue(value) {
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
convertJsonToJSValue(value) {
|
|
56
|
+
return value;
|
|
57
|
+
}
|
|
58
|
+
marshallArray(values) {
|
|
59
|
+
return values;
|
|
60
|
+
}
|
|
61
|
+
cloneEmbeddable(data) {
|
|
62
|
+
const ret = super.cloneEmbeddable(data);
|
|
63
|
+
core_1.Utils.dropUndefinedProperties(ret);
|
|
64
|
+
return ret;
|
|
65
|
+
}
|
|
66
|
+
shouldHaveColumn(prop, populate, exclude) {
|
|
67
|
+
if (super.shouldHaveColumn(prop, populate, exclude)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return prop.kind === core_1.ReferenceKind.MANY_TO_MANY && prop.owner;
|
|
71
|
+
}
|
|
72
|
+
validateMetadata(meta) {
|
|
73
|
+
const pk = meta.getPrimaryProps()[0];
|
|
74
|
+
if (pk && pk.fieldNames?.[0] !== "_id") {
|
|
75
|
+
throw core_1.MetadataError.invalidPrimaryKey(meta, pk, "_id");
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
isAllowedTopLevelOperator(operator) {
|
|
79
|
+
return ["$not", "$fulltext"].includes(operator);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.MongoPlatform = MongoPlatform;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { AbstractSchemaGenerator, type CreateSchemaOptions, type MikroORM } from "@yandjin-mikro-orm/core";
|
|
2
|
+
import type { MongoDriver } from "./MongoDriver";
|
|
3
|
+
export declare class MongoSchemaGenerator extends AbstractSchemaGenerator<MongoDriver> {
|
|
4
|
+
static register(orm: MikroORM): void;
|
|
5
|
+
createSchema(options?: MongoCreateSchemaOptions): Promise<void>;
|
|
6
|
+
dropSchema(options?: {
|
|
7
|
+
dropMigrationsTable?: boolean;
|
|
8
|
+
}): Promise<void>;
|
|
9
|
+
updateSchema(options?: MongoCreateSchemaOptions): Promise<void>;
|
|
10
|
+
ensureDatabase(): Promise<boolean>;
|
|
11
|
+
refreshDatabase(options?: MongoCreateSchemaOptions): Promise<void>;
|
|
12
|
+
dropIndexes(options?: {
|
|
13
|
+
skipIndexes?: {
|
|
14
|
+
collection: string;
|
|
15
|
+
indexName: string;
|
|
16
|
+
}[];
|
|
17
|
+
collectionsWithFailedIndexes?: string[];
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
ensureIndexes(options?: EnsureIndexesOptions): Promise<void>;
|
|
20
|
+
private createIndexes;
|
|
21
|
+
private createUniqueIndexes;
|
|
22
|
+
private createPropertyIndexes;
|
|
23
|
+
}
|
|
24
|
+
export interface MongoCreateSchemaOptions extends CreateSchemaOptions {
|
|
25
|
+
/** create indexes? defaults to true */
|
|
26
|
+
ensureIndexes?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface EnsureIndexesOptions {
|
|
29
|
+
ensureCollections?: boolean;
|
|
30
|
+
retry?: boolean | string[];
|
|
31
|
+
retryLimit?: number;
|
|
32
|
+
}
|