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 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
- return keyLower.endsWith("id") && relationNameLower.includes(keyLower.replace(/id$/, ""));
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
- [relationName]: null
1333
- };
1334
- if (fkFieldName in entity) {
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 assembler = nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
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
- return relationMeta.entity();
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();