nestjs-query-mikro-orm 0.1.0 → 0.1.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/dist/index.cjs CHANGED
@@ -840,7 +840,14 @@ var RelationQueryBuilder = class {
840
840
  const entityKeys = Object.keys(entityAsRecord);
841
841
  const matchingKey = entityKeys.find((key) => {
842
842
  const keyLower = key.toLowerCase();
843
- return keyLower.endsWith("id") && relationNameLower.includes(keyLower.replace(/id$/, ""));
843
+ if (keyLower === "id" || !keyLower.endsWith("id")) {
844
+ return false;
845
+ }
846
+ const base = keyLower.replace(/id$/, "");
847
+ if (!base) {
848
+ return false;
849
+ }
850
+ return relationNameLower.includes(base);
844
851
  });
845
852
  if (matchingKey) {
846
853
  fkValue = entityAsRecord[matchingKey];
@@ -1174,6 +1181,10 @@ var RelationQueryService = class {
1174
1181
  if (Array.isArray(dto)) {
1175
1182
  return this.batchQueryRelations(RelationClass, relationName, dto, query);
1176
1183
  }
1184
+ if (this.isRelationClassIdentity(RelationClass, relationName)) {
1185
+ const relationQueryBuilder2 = this.getRelationQueryBuilder(relationName);
1186
+ return await relationQueryBuilder2.selectAndExecute(dto, query);
1187
+ }
1177
1188
  const assembler = nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
1178
1189
  const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
1179
1190
  return assembler.convertToDTOs(await relationQueryBuilder.selectAndExecute(dto, assembler.convertQuery(query)));
@@ -1207,6 +1218,16 @@ var RelationQueryService = class {
1207
1218
  if (Array.isArray(dto)) {
1208
1219
  return this.batchFindRelations(RelationClass, relationName, dto, opts);
1209
1220
  }
1221
+ if (this.isRelationClassIdentity(RelationClass, relationName)) {
1222
+ const relationQueryBuilder2 = this.getRelationQueryBuilder(relationName);
1223
+ const relations2 = await relationQueryBuilder2.selectAndExecute(dto, {
1224
+ filter: opts?.filter,
1225
+ paging: {
1226
+ limit: 1
1227
+ }
1228
+ });
1229
+ return relations2[0];
1230
+ }
1210
1231
  const assembler = nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
1211
1232
  const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
1212
1233
  const relations = await relationQueryBuilder.selectAndExecute(dto, {
@@ -1227,10 +1248,20 @@ var RelationQueryService = class {
1227
1248
  */
1228
1249
  async addRelations(relationName, id, relationIds, opts) {
1229
1250
  const entity = await this.getById(id, opts);
1251
+ const meta = this.getRelationMeta(relationName);
1230
1252
  const relations = await this.getRelations(relationName, relationIds, opts?.relationFilter);
1231
1253
  if (!this.foundAllRelations(relationIds, relations)) {
1232
1254
  throw new Error(`Unable to find all ${relationName} to add to ${this.EntityClass.name}`);
1233
1255
  }
1256
+ if (meta.kind === "1:m" && meta.mappedBy) {
1257
+ for (const relation of relations) {
1258
+ core.wrap(relation).assign({
1259
+ [meta.mappedBy]: entity
1260
+ });
1261
+ }
1262
+ await this.repo.getEntityManager().flush();
1263
+ return entity;
1264
+ }
1234
1265
  const collection = entity[relationName];
1235
1266
  if (collection && typeof collection.add === "function") {
1236
1267
  for (const relation of relations) {
@@ -1251,12 +1282,33 @@ var RelationQueryService = class {
1251
1282
  */
1252
1283
  async setRelations(relationName, id, relationIds, opts) {
1253
1284
  const entity = await this.getById(id, opts);
1285
+ const meta = this.getRelationMeta(relationName);
1254
1286
  const relations = await this.getRelations(relationName, relationIds, opts?.relationFilter);
1255
1287
  if (relationIds.length) {
1256
1288
  if (!this.foundAllRelations(relationIds, relations)) {
1257
1289
  throw new Error(`Unable to find all ${relationName} to set on ${this.EntityClass.name}`);
1258
1290
  }
1259
1291
  }
1292
+ if (meta.kind === "1:m" && meta.mappedBy) {
1293
+ const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
1294
+ const currentRelations = await relationQueryBuilder.selectAndExecute(entity, {});
1295
+ const nextSet = new Set(relations.map((r) => core.wrap(r).getPrimaryKey()));
1296
+ for (const currentRelation of currentRelations) {
1297
+ const currentPk = core.wrap(currentRelation).getPrimaryKey();
1298
+ if (!nextSet.has(currentPk)) {
1299
+ core.wrap(currentRelation).assign({
1300
+ [meta.mappedBy]: null
1301
+ });
1302
+ }
1303
+ }
1304
+ for (const relation of relations) {
1305
+ core.wrap(relation).assign({
1306
+ [meta.mappedBy]: entity
1307
+ });
1308
+ }
1309
+ await this.repo.getEntityManager().flush();
1310
+ return entity;
1311
+ }
1260
1312
  const collection = entity[relationName];
1261
1313
  if (collection && typeof collection.set === "function") {
1262
1314
  await collection.init();
@@ -1296,10 +1348,20 @@ var RelationQueryService = class {
1296
1348
  */
1297
1349
  async removeRelations(relationName, id, relationIds, opts) {
1298
1350
  const entity = await this.getById(id, opts);
1351
+ const meta = this.getRelationMeta(relationName);
1299
1352
  const relations = await this.getRelations(relationName, relationIds, opts?.relationFilter);
1300
1353
  if (!this.foundAllRelations(relationIds, relations)) {
1301
1354
  throw new Error(`Unable to find all ${relationName} to remove from ${this.EntityClass.name}`);
1302
1355
  }
1356
+ if (meta.kind === "1:m" && meta.mappedBy) {
1357
+ for (const relation of relations) {
1358
+ core.wrap(relation).assign({
1359
+ [meta.mappedBy]: null
1360
+ });
1361
+ }
1362
+ await this.repo.getEntityManager().flush();
1363
+ return entity;
1364
+ }
1303
1365
  const collection = entity[relationName];
1304
1366
  if (collection && typeof collection.remove === "function") {
1305
1367
  await collection.init();
@@ -1328,14 +1390,25 @@ var RelationQueryService = class {
1328
1390
  const meta = this.getRelationMeta(relationName);
1329
1391
  if (meta.kind === "1:1" || meta.kind === "m:1") {
1330
1392
  const fkFieldName = `${relationName}Id`;
1331
- const assignData = {
1332
- [relationName]: null
1333
- };
1334
- if (fkFieldName in entity) {
1393
+ const assignData = {};
1394
+ const ownDescriptor = Object.getOwnPropertyDescriptor(entity, fkFieldName);
1395
+ const protoDescriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(entity), fkFieldName);
1396
+ const descriptor = ownDescriptor ?? protoDescriptor;
1397
+ const canAssignFk = fkFieldName in entity && (!descriptor || Boolean(descriptor.set) || descriptor.writable === true);
1398
+ if (canAssignFk) {
1335
1399
  assignData[fkFieldName] = null;
1400
+ } else {
1401
+ assignData[relationName] = null;
1336
1402
  }
1337
1403
  core.wrap(entity).assign(assignData);
1338
1404
  } else {
1405
+ if (meta.kind === "1:m" && meta.mappedBy) {
1406
+ core.wrap(relation).assign({
1407
+ [meta.mappedBy]: null
1408
+ });
1409
+ await this.repo.getEntityManager().flush();
1410
+ return entity;
1411
+ }
1339
1412
  const collection = entity[relationName];
1340
1413
  if (collection && typeof collection.remove === "function") {
1341
1414
  await collection.init();
@@ -1356,13 +1429,14 @@ var RelationQueryService = class {
1356
1429
  * @param query - A query to filter, page or sort relations.
1357
1430
  */
1358
1431
  async batchQueryRelations(RelationClass, relationName, entities, query) {
1359
- const assembler = nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
1432
+ const bypassAssembler = this.isRelationClassIdentity(RelationClass, relationName);
1433
+ const assembler = bypassAssembler ? void 0 : nestjsQueryCore.AssemblerFactory.getAssembler(RelationClass, this.getRelationEntity(relationName));
1360
1434
  const relationQueryBuilder = this.getRelationQueryBuilder(relationName);
1361
- const convertedQuery = assembler.convertQuery(query);
1435
+ const convertedQuery = assembler ? assembler.convertQuery(query) : query;
1362
1436
  const results = /* @__PURE__ */ new Map();
1363
1437
  await Promise.all(entities.map(async (entity) => {
1364
1438
  const relations = await relationQueryBuilder.selectAndExecute(entity, convertedQuery);
1365
- const relationDtos = await assembler.convertToDTOs(relations);
1439
+ const relationDtos = bypassAssembler ? relations : await assembler.convertToDTOs(relations);
1366
1440
  if (relationDtos.length > 0) {
1367
1441
  results.set(entity, relationDtos);
1368
1442
  }
@@ -1432,6 +1506,10 @@ var RelationQueryService = class {
1432
1506
  });
1433
1507
  return results;
1434
1508
  }
1509
+ isRelationClassIdentity(RelationClass, relationName) {
1510
+ const relationEntity = this.getRelationEntity(relationName);
1511
+ return RelationClass === relationEntity || RelationClass.name === relationEntity.name;
1512
+ }
1435
1513
  getRelationMeta(relationName) {
1436
1514
  const em = this.repo.getEntityManager();
1437
1515
  const metadata = em.getMetadata().get(this.repo.getEntityName());
@@ -1442,12 +1520,14 @@ var RelationQueryService = class {
1442
1520
  return {
1443
1521
  kind: relationMeta.kind,
1444
1522
  type: relationMeta.type,
1445
- entity: relationMeta.entity
1523
+ entity: relationMeta.entity,
1524
+ mappedBy: relationMeta.mappedBy
1446
1525
  };
1447
1526
  }
1448
1527
  getRelationEntity(relationName) {
1449
1528
  const relationMeta = this.getRelationMeta(relationName);
1450
- return relationMeta.entity();
1529
+ const entity = relationMeta.entity();
1530
+ return entity && "class" in entity ? entity.class : entity;
1451
1531
  }
1452
1532
  async getRelations(relationName, ids, filter) {
1453
1533
  const em = this.repo.getEntityManager();
@@ -1509,7 +1589,7 @@ var MikroOrmQueryService = class extends RelationQueryService {
1509
1589
  return data;
1510
1590
  })(this.EntityClass);
1511
1591
  nestjsQueryCore.AssemblerDeserializer((d) => {
1512
- const entity = this.repo.getEntityManager().create(this.EntityClass, classTransformer.instanceToPlain(d));
1592
+ const entity = this.repo.getEntityManager().merge(this.EntityClass, d);
1513
1593
  return entity;
1514
1594
  })(this.EntityClass);
1515
1595
  }