nestjs-query-mikro-orm 0.1.0 → 0.1.2
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/index.cjs +90 -34
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +91 -35
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
var nestjs = require('@mikro-orm/nestjs');
|
|
4
4
|
var nestjsQueryCore = require('@ptc-org/nestjs-query-core');
|
|
5
5
|
var core = require('@mikro-orm/core');
|
|
6
|
-
var assembler_serializer = require('@ptc-org/nestjs-query-core/src/assemblers/assembler.serializer');
|
|
7
6
|
var common = require('@nestjs/common');
|
|
8
|
-
var classTransformer = require('class-transformer');
|
|
9
7
|
var merge = require('lodash.merge');
|
|
10
8
|
|
|
11
9
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
@@ -840,7 +838,14 @@ var RelationQueryBuilder = class {
|
|
|
840
838
|
const entityKeys = Object.keys(entityAsRecord);
|
|
841
839
|
const matchingKey = entityKeys.find((key) => {
|
|
842
840
|
const keyLower = key.toLowerCase();
|
|
843
|
-
|
|
841
|
+
if (keyLower === "id" || !keyLower.endsWith("id")) {
|
|
842
|
+
return false;
|
|
843
|
+
}
|
|
844
|
+
const base = keyLower.replace(/id$/, "");
|
|
845
|
+
if (!base) {
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
848
|
+
return relationNameLower.includes(base);
|
|
844
849
|
});
|
|
845
850
|
if (matchingKey) {
|
|
846
851
|
fkValue = entityAsRecord[matchingKey];
|
|
@@ -1174,6 +1179,10 @@ var RelationQueryService = class {
|
|
|
1174
1179
|
if (Array.isArray(dto)) {
|
|
1175
1180
|
return this.batchQueryRelations(RelationClass, relationName, dto, query);
|
|
1176
1181
|
}
|
|
1182
|
+
if (this.isRelationClassIdentity(RelationClass, relationName)) {
|
|
1183
|
+
const relationQueryBuilder2 = this.getRelationQueryBuilder(relationName);
|
|
1184
|
+
return await relationQueryBuilder2.selectAndExecute(dto, query);
|
|
1185
|
+
}
|
|
1177
1186
|
const assembler = nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
|
|
1178
1187
|
const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
|
|
1179
1188
|
return assembler.convertToDTOs(await relationQueryBuilder.selectAndExecute(dto, assembler.convertQuery(query)));
|
|
@@ -1207,6 +1216,16 @@ var RelationQueryService = class {
|
|
|
1207
1216
|
if (Array.isArray(dto)) {
|
|
1208
1217
|
return this.batchFindRelations(RelationClass, relationName, dto, opts);
|
|
1209
1218
|
}
|
|
1219
|
+
if (this.isRelationClassIdentity(RelationClass, relationName)) {
|
|
1220
|
+
const relationQueryBuilder2 = this.getRelationQueryBuilder(relationName);
|
|
1221
|
+
const relations2 = await relationQueryBuilder2.selectAndExecute(dto, {
|
|
1222
|
+
filter: opts?.filter,
|
|
1223
|
+
paging: {
|
|
1224
|
+
limit: 1
|
|
1225
|
+
}
|
|
1226
|
+
});
|
|
1227
|
+
return relations2[0];
|
|
1228
|
+
}
|
|
1210
1229
|
const assembler = nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
|
|
1211
1230
|
const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
|
|
1212
1231
|
const relations = await relationQueryBuilder.selectAndExecute(dto, {
|
|
@@ -1227,10 +1246,20 @@ var RelationQueryService = class {
|
|
|
1227
1246
|
*/
|
|
1228
1247
|
async addRelations(relationName, id, relationIds, opts) {
|
|
1229
1248
|
const entity = await this.getById(id, opts);
|
|
1249
|
+
const meta = this.getRelationMeta(relationName);
|
|
1230
1250
|
const relations = await this.getRelations(relationName, relationIds, opts?.relationFilter);
|
|
1231
1251
|
if (!this.foundAllRelations(relationIds, relations)) {
|
|
1232
1252
|
throw new Error(`Unable to find all ${relationName} to add to ${this.EntityClass.name}`);
|
|
1233
1253
|
}
|
|
1254
|
+
if (meta.kind === "1:m" && meta.mappedBy) {
|
|
1255
|
+
for (const relation of relations) {
|
|
1256
|
+
core.wrap(relation).assign({
|
|
1257
|
+
[meta.mappedBy]: entity
|
|
1258
|
+
});
|
|
1259
|
+
}
|
|
1260
|
+
await this.repo.getEntityManager().flush();
|
|
1261
|
+
return entity;
|
|
1262
|
+
}
|
|
1234
1263
|
const collection = entity[relationName];
|
|
1235
1264
|
if (collection && typeof collection.add === "function") {
|
|
1236
1265
|
for (const relation of relations) {
|
|
@@ -1251,12 +1280,33 @@ var RelationQueryService = class {
|
|
|
1251
1280
|
*/
|
|
1252
1281
|
async setRelations(relationName, id, relationIds, opts) {
|
|
1253
1282
|
const entity = await this.getById(id, opts);
|
|
1283
|
+
const meta = this.getRelationMeta(relationName);
|
|
1254
1284
|
const relations = await this.getRelations(relationName, relationIds, opts?.relationFilter);
|
|
1255
1285
|
if (relationIds.length) {
|
|
1256
1286
|
if (!this.foundAllRelations(relationIds, relations)) {
|
|
1257
1287
|
throw new Error(`Unable to find all ${relationName} to set on ${this.EntityClass.name}`);
|
|
1258
1288
|
}
|
|
1259
1289
|
}
|
|
1290
|
+
if (meta.kind === "1:m" && meta.mappedBy) {
|
|
1291
|
+
const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
|
|
1292
|
+
const currentRelations = await relationQueryBuilder.selectAndExecute(entity, {});
|
|
1293
|
+
const nextSet = new Set(relations.map((r) => core.wrap(r).getPrimaryKey()));
|
|
1294
|
+
for (const currentRelation of currentRelations) {
|
|
1295
|
+
const currentPk = core.wrap(currentRelation).getPrimaryKey();
|
|
1296
|
+
if (!nextSet.has(currentPk)) {
|
|
1297
|
+
core.wrap(currentRelation).assign({
|
|
1298
|
+
[meta.mappedBy]: null
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
for (const relation of relations) {
|
|
1303
|
+
core.wrap(relation).assign({
|
|
1304
|
+
[meta.mappedBy]: entity
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
await this.repo.getEntityManager().flush();
|
|
1308
|
+
return entity;
|
|
1309
|
+
}
|
|
1260
1310
|
const collection = entity[relationName];
|
|
1261
1311
|
if (collection && typeof collection.set === "function") {
|
|
1262
1312
|
await collection.init();
|
|
@@ -1296,10 +1346,20 @@ var RelationQueryService = class {
|
|
|
1296
1346
|
*/
|
|
1297
1347
|
async removeRelations(relationName, id, relationIds, opts) {
|
|
1298
1348
|
const entity = await this.getById(id, opts);
|
|
1349
|
+
const meta = this.getRelationMeta(relationName);
|
|
1299
1350
|
const relations = await this.getRelations(relationName, relationIds, opts?.relationFilter);
|
|
1300
1351
|
if (!this.foundAllRelations(relationIds, relations)) {
|
|
1301
1352
|
throw new Error(`Unable to find all ${relationName} to remove from ${this.EntityClass.name}`);
|
|
1302
1353
|
}
|
|
1354
|
+
if (meta.kind === "1:m" && meta.mappedBy) {
|
|
1355
|
+
for (const relation of relations) {
|
|
1356
|
+
core.wrap(relation).assign({
|
|
1357
|
+
[meta.mappedBy]: null
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
await this.repo.getEntityManager().flush();
|
|
1361
|
+
return entity;
|
|
1362
|
+
}
|
|
1303
1363
|
const collection = entity[relationName];
|
|
1304
1364
|
if (collection && typeof collection.remove === "function") {
|
|
1305
1365
|
await collection.init();
|
|
@@ -1328,14 +1388,25 @@ var RelationQueryService = class {
|
|
|
1328
1388
|
const meta = this.getRelationMeta(relationName);
|
|
1329
1389
|
if (meta.kind === "1:1" || meta.kind === "m:1") {
|
|
1330
1390
|
const fkFieldName = `${relationName}Id`;
|
|
1331
|
-
const assignData = {
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1391
|
+
const assignData = {};
|
|
1392
|
+
const ownDescriptor = Object.getOwnPropertyDescriptor(entity, fkFieldName);
|
|
1393
|
+
const protoDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(entity), fkFieldName);
|
|
1394
|
+
const descriptor = ownDescriptor ?? protoDescriptor;
|
|
1395
|
+
const canAssignFk = fkFieldName in entity && (!descriptor || Boolean(descriptor.set) || descriptor.writable === true);
|
|
1396
|
+
if (canAssignFk) {
|
|
1335
1397
|
assignData[fkFieldName] = null;
|
|
1398
|
+
} else {
|
|
1399
|
+
assignData[relationName] = null;
|
|
1336
1400
|
}
|
|
1337
1401
|
core.wrap(entity).assign(assignData);
|
|
1338
1402
|
} else {
|
|
1403
|
+
if (meta.kind === "1:m" && meta.mappedBy) {
|
|
1404
|
+
core.wrap(relation).assign({
|
|
1405
|
+
[meta.mappedBy]: null
|
|
1406
|
+
});
|
|
1407
|
+
await this.repo.getEntityManager().flush();
|
|
1408
|
+
return entity;
|
|
1409
|
+
}
|
|
1339
1410
|
const collection = entity[relationName];
|
|
1340
1411
|
if (collection && typeof collection.remove === "function") {
|
|
1341
1412
|
await collection.init();
|
|
@@ -1356,13 +1427,14 @@ var RelationQueryService = class {
|
|
|
1356
1427
|
* @param query - A query to filter, page or sort relations.
|
|
1357
1428
|
*/
|
|
1358
1429
|
async batchQueryRelations(RelationClass, relationName, entities, query) {
|
|
1359
|
-
const
|
|
1430
|
+
const bypassAssembler = this.isRelationClassIdentity(RelationClass, relationName);
|
|
1431
|
+
const assembler = bypassAssembler ? void 0 : nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
|
|
1360
1432
|
const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
|
|
1361
|
-
const convertedQuery = assembler.convertQuery(query);
|
|
1433
|
+
const convertedQuery = assembler ? assembler.convertQuery(query) : query;
|
|
1362
1434
|
const results = /* @__PURE__ */ new Map();
|
|
1363
1435
|
await Promise.all(entities.map(async (entity) => {
|
|
1364
1436
|
const relations = await relationQueryBuilder.selectAndExecute(entity, convertedQuery);
|
|
1365
|
-
const relationDtos = await assembler.convertToDTOs(relations);
|
|
1437
|
+
const relationDtos = bypassAssembler ? relations : await assembler.convertToDTOs(relations);
|
|
1366
1438
|
if (relationDtos.length > 0) {
|
|
1367
1439
|
results.set(entity, relationDtos);
|
|
1368
1440
|
}
|
|
@@ -1432,6 +1504,10 @@ var RelationQueryService = class {
|
|
|
1432
1504
|
});
|
|
1433
1505
|
return results;
|
|
1434
1506
|
}
|
|
1507
|
+
isRelationClassIdentity(RelationClass, relationName) {
|
|
1508
|
+
const relationEntity = this.getRelationEntity(relationName);
|
|
1509
|
+
return RelationClass === relationEntity || RelationClass.name === relationEntity.name;
|
|
1510
|
+
}
|
|
1435
1511
|
getRelationMeta(relationName) {
|
|
1436
1512
|
const em = this.repo.getEntityManager();
|
|
1437
1513
|
const metadata = em.getMetadata().get(this.repo.getEntityName());
|
|
@@ -1442,12 +1518,14 @@ var RelationQueryService = class {
|
|
|
1442
1518
|
return {
|
|
1443
1519
|
kind: relationMeta.kind,
|
|
1444
1520
|
type: relationMeta.type,
|
|
1445
|
-
entity: relationMeta.entity
|
|
1521
|
+
entity: relationMeta.entity,
|
|
1522
|
+
mappedBy: relationMeta.mappedBy
|
|
1446
1523
|
};
|
|
1447
1524
|
}
|
|
1448
1525
|
getRelationEntity(relationName) {
|
|
1449
1526
|
const relationMeta = this.getRelationMeta(relationName);
|
|
1450
|
-
|
|
1527
|
+
const entity = relationMeta.entity();
|
|
1528
|
+
return entity && "class" in entity ? entity.class : entity;
|
|
1451
1529
|
}
|
|
1452
1530
|
async getRelations(relationName, ids, filter) {
|
|
1453
1531
|
const em = this.repo.getEntityManager();
|
|
@@ -1491,28 +1569,6 @@ var MikroOrmQueryService = class extends RelationQueryService {
|
|
|
1491
1569
|
super(), this.repo = repo;
|
|
1492
1570
|
this.filterQueryBuilder = opts?.filterQueryBuilder ?? new FilterQueryBuilder(this.repo);
|
|
1493
1571
|
this.useSoftDelete = opts?.useSoftDelete ?? false;
|
|
1494
|
-
const serializer = assembler_serializer.getAssemblerSerializer(this.EntityClass);
|
|
1495
|
-
if (!serializer) {
|
|
1496
|
-
nestjsQueryCore.AssemblerSerializer((e) => {
|
|
1497
|
-
const json = classTransformer.instanceToPlain(e, {
|
|
1498
|
-
enableImplicitConversion: true,
|
|
1499
|
-
excludeExtraneousValues: true,
|
|
1500
|
-
exposeDefaultValues: true
|
|
1501
|
-
});
|
|
1502
|
-
const jsonWithRemovedEmptyObjects = Object.fromEntries(Object.entries(json).filter(([, value]) => !(value && typeof value === "object" && !Array.isArray(value) && Object.keys(value).length === 0)));
|
|
1503
|
-
const wrapped = core.wrap(e, true);
|
|
1504
|
-
const ormJson = "toObject" in wrapped ? wrapped.toObject() : {};
|
|
1505
|
-
const data = {
|
|
1506
|
-
...ormJson,
|
|
1507
|
-
...jsonWithRemovedEmptyObjects
|
|
1508
|
-
};
|
|
1509
|
-
return data;
|
|
1510
|
-
})(this.EntityClass);
|
|
1511
|
-
nestjsQueryCore.AssemblerDeserializer((d) => {
|
|
1512
|
-
const entity = this.repo.getEntityManager().create(this.EntityClass, classTransformer.instanceToPlain(d));
|
|
1513
|
-
return entity;
|
|
1514
|
-
})(this.EntityClass);
|
|
1515
|
-
}
|
|
1516
1572
|
}
|
|
1517
1573
|
get EntityClass() {
|
|
1518
1574
|
const em = this.repo.getEntityManager();
|