@forklaunch/implementation-iam-base 0.1.17 → 0.2.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.
@@ -1,14 +1,16 @@
1
1
  import { IdDto, InstanceTypeRecord } from '@forklaunch/common';
2
+ import {
3
+ evaluateTelemetryOptions,
4
+ MetricsDefinition,
5
+ OpenTelemetryCollector,
6
+ TelemetryOptions
7
+ } from '@forklaunch/core/http';
2
8
  import {
3
9
  InternalDtoMapper,
4
10
  RequestDtoMapperConstructor,
5
11
  ResponseDtoMapperConstructor,
6
12
  transformIntoInternalDtoMapper
7
13
  } from '@forklaunch/core/mappers';
8
- import {
9
- MetricsDefinition,
10
- OpenTelemetryCollector
11
- } from '@forklaunch/core/http';
12
14
  import { MapNestedDtoArraysToCollections } from '@forklaunch/core/services';
13
15
  import { OrganizationService } from '@forklaunch/interfaces-iam/interfaces';
14
16
  import {
@@ -61,17 +63,22 @@ export class BaseOrganizationService<
61
63
  }
62
64
  > implements OrganizationService<OrganizationStatus>
63
65
  {
64
- #mapperss: InternalDtoMapper<
65
- InstanceTypeRecord<typeof this.mapperss>,
66
+ #mappers: InternalDtoMapper<
67
+ InstanceTypeRecord<typeof this.mappers>,
66
68
  Entities,
67
69
  Dto
68
70
  >;
71
+ private evaluatedTelemetryOptions: {
72
+ logging?: boolean;
73
+ metrics?: boolean;
74
+ tracing?: boolean;
75
+ };
69
76
 
70
77
  constructor(
71
78
  public em: EntityManager,
72
79
  protected openTelemetryCollector: OpenTelemetryCollector<Metrics>,
73
80
  protected schemaValidator: SchemaValidator,
74
- protected mapperss: {
81
+ protected mappers: {
75
82
  OrganizationDtoMapper: ResponseDtoMapperConstructor<
76
83
  SchemaValidator,
77
84
  Dto['OrganizationDtoMapper'],
@@ -87,25 +94,45 @@ export class BaseOrganizationService<
87
94
  Dto['UpdateOrganizationDtoMapper'],
88
95
  Entities['UpdateOrganizationDtoMapper']
89
96
  >;
97
+ },
98
+ options?: {
99
+ telemetry?: TelemetryOptions;
90
100
  }
91
101
  ) {
92
- this.#mapperss = transformIntoInternalDtoMapper(mapperss, schemaValidator);
102
+ this.#mappers = transformIntoInternalDtoMapper(mappers, schemaValidator);
103
+ this.evaluatedTelemetryOptions = options?.telemetry
104
+ ? evaluateTelemetryOptions(options.telemetry).enabled
105
+ : {
106
+ logging: false,
107
+ metrics: false,
108
+ tracing: false
109
+ };
93
110
  }
94
111
 
95
112
  async createOrganization(
96
113
  organizationDto: Dto['CreateOrganizationDtoMapper'],
97
114
  em?: EntityManager
98
115
  ): Promise<Dto['OrganizationDtoMapper']> {
99
- this.openTelemetryCollector.log('info', 'Creating organization');
100
- const organization =
101
- this.#mapperss.CreateOrganizationDtoMapper.deserializeDtoToEntity(
116
+ if (this.evaluatedTelemetryOptions.logging) {
117
+ this.openTelemetryCollector.info(
118
+ 'Creating organization',
102
119
  organizationDto
103
120
  );
104
- await (em ?? this.em).transactional(async (innerEm) => {
105
- await innerEm.persist(organization);
106
- });
121
+ }
122
+
123
+ const organization =
124
+ await this.#mappers.CreateOrganizationDtoMapper.deserializeDtoToEntity(
125
+ organizationDto,
126
+ em ?? this.em
127
+ );
107
128
 
108
- return this.#mapperss.OrganizationDtoMapper.serializeEntityToDto(
129
+ if (em) {
130
+ await em.persist(organization);
131
+ } else {
132
+ await this.em.persistAndFlush(organization);
133
+ }
134
+
135
+ return this.#mappers.OrganizationDtoMapper.serializeEntityToDto(
109
136
  organization
110
137
  );
111
138
  }
@@ -114,11 +141,16 @@ export class BaseOrganizationService<
114
141
  idDto: IdDto,
115
142
  em?: EntityManager
116
143
  ): Promise<Dto['OrganizationDtoMapper']> {
144
+ if (this.evaluatedTelemetryOptions.logging) {
145
+ this.openTelemetryCollector.info('Getting organization', idDto);
146
+ }
147
+
117
148
  const organization = await (em ?? this.em).findOneOrFail(
118
149
  'Organization',
119
150
  idDto
120
151
  );
121
- return this.#mapperss.OrganizationDtoMapper.serializeEntityToDto(
152
+
153
+ return this.#mappers.OrganizationDtoMapper.serializeEntityToDto(
122
154
  organization as Entities['OrganizationDtoMapper']
123
155
  );
124
156
  }
@@ -127,17 +159,39 @@ export class BaseOrganizationService<
127
159
  organizationDto: Dto['UpdateOrganizationDtoMapper'],
128
160
  em?: EntityManager
129
161
  ): Promise<Dto['OrganizationDtoMapper']> {
130
- const updatedOrganization =
131
- this.#mapperss.UpdateOrganizationDtoMapper.deserializeDtoToEntity(
162
+ if (this.evaluatedTelemetryOptions.logging) {
163
+ this.openTelemetryCollector.info(
164
+ 'Updating organization',
132
165
  organizationDto
133
166
  );
134
- await (em ?? this.em).upsert(updatedOrganization);
135
- return this.#mapperss.OrganizationDtoMapper.serializeEntityToDto(
167
+ }
168
+
169
+ const updatedOrganization =
170
+ await this.#mappers.UpdateOrganizationDtoMapper.deserializeDtoToEntity(
171
+ organizationDto,
172
+ em ?? this.em
173
+ );
174
+
175
+ if (em) {
176
+ await em.persist(updatedOrganization);
177
+ } else {
178
+ await this.em.persistAndFlush(updatedOrganization);
179
+ }
180
+
181
+ return this.#mappers.OrganizationDtoMapper.serializeEntityToDto(
136
182
  updatedOrganization
137
183
  );
138
184
  }
139
185
 
140
186
  async deleteOrganization(idDto: IdDto, em?: EntityManager): Promise<void> {
141
- await (em ?? this.em).nativeDelete('Organization', idDto);
187
+ if (this.evaluatedTelemetryOptions.logging) {
188
+ this.openTelemetryCollector.info('Deleting organization', idDto);
189
+ }
190
+
191
+ if (em) {
192
+ await em.nativeDelete('Organization', idDto);
193
+ } else {
194
+ await this.em.nativeDelete('Organization', idDto);
195
+ }
142
196
  }
143
197
  }
@@ -4,22 +4,24 @@ import {
4
4
  } from '@forklaunch/interfaces-iam/interfaces';
5
5
 
6
6
  import { IdDto, IdsDto, InstanceTypeRecord } from '@forklaunch/common';
7
+ import {
8
+ evaluateTelemetryOptions,
9
+ MetricsDefinition,
10
+ OpenTelemetryCollector,
11
+ TelemetryOptions
12
+ } from '@forklaunch/core/http';
7
13
  import {
8
14
  InternalDtoMapper,
9
15
  RequestDtoMapperConstructor,
10
16
  ResponseDtoMapperConstructor,
11
17
  transformIntoInternalDtoMapper
12
18
  } from '@forklaunch/core/mappers';
13
- import {
14
- MetricsDefinition,
15
- OpenTelemetryCollector
16
- } from '@forklaunch/core/http';
17
19
  import { MapNestedDtoArraysToCollections } from '@forklaunch/core/services';
18
20
  import {
19
21
  CreatePermissionDto,
20
22
  PermissionDto,
21
- RoleDto,
22
- UpdatePermissionDto
23
+ UpdatePermissionDto,
24
+ UpdateRoleDto
23
25
  } from '@forklaunch/interfaces-iam/types';
24
26
  import { AnySchemaValidator } from '@forklaunch/validator';
25
27
  import { EntityManager } from '@mikro-orm/core';
@@ -31,38 +33,49 @@ export class BasePermissionService<
31
33
  PermissionDtoMapper: PermissionDto;
32
34
  CreatePermissionDtoMapper: CreatePermissionDto;
33
35
  UpdatePermissionDtoMapper: UpdatePermissionDto;
34
- RoleDtoMapper: RoleDto;
36
+ RoleEntityMapper: UpdateRoleDto;
35
37
  } = {
36
38
  PermissionDtoMapper: PermissionDto;
37
39
  CreatePermissionDtoMapper: CreatePermissionDto;
38
40
  UpdatePermissionDtoMapper: UpdatePermissionDto;
39
- RoleDtoMapper: RoleDto;
41
+ RoleEntityMapper: UpdateRoleDto;
40
42
  },
41
43
  Entities extends {
42
44
  PermissionDtoMapper: PermissionDto;
43
45
  CreatePermissionDtoMapper: PermissionDto;
44
46
  UpdatePermissionDtoMapper: PermissionDto;
45
- RoleDtoMapper: MapNestedDtoArraysToCollections<RoleDto, 'permissions'>;
47
+ RoleEntityMapper: MapNestedDtoArraysToCollections<
48
+ UpdateRoleDto,
49
+ 'permissions'
50
+ >;
46
51
  } = {
47
52
  PermissionDtoMapper: PermissionDto;
48
53
  CreatePermissionDtoMapper: PermissionDto;
49
54
  UpdatePermissionDtoMapper: PermissionDto;
50
- RoleDtoMapper: MapNestedDtoArraysToCollections<RoleDto, 'permissions'>;
55
+ RoleEntityMapper: MapNestedDtoArraysToCollections<
56
+ UpdateRoleDto,
57
+ 'permissions'
58
+ >;
51
59
  }
52
60
  > implements PermissionService
53
61
  {
54
- #mapperss: InternalDtoMapper<
55
- InstanceTypeRecord<typeof this.mapperss>,
62
+ #mappers: InternalDtoMapper<
63
+ InstanceTypeRecord<typeof this.mappers>,
56
64
  Entities,
57
65
  Dto
58
66
  >;
67
+ private evaluatedTelemetryOptions: {
68
+ logging?: boolean;
69
+ metrics?: boolean;
70
+ tracing?: boolean;
71
+ };
59
72
 
60
73
  constructor(
61
74
  public em: EntityManager,
62
75
  protected roleServiceFactory: () => RoleService,
63
76
  protected openTelemetryCollector: OpenTelemetryCollector<Metrics>,
64
77
  protected schemaValidator: SchemaValidator,
65
- protected mapperss: {
78
+ protected mappers: {
66
79
  PermissionDtoMapper: ResponseDtoMapperConstructor<
67
80
  SchemaValidator,
68
81
  Dto['PermissionDtoMapper'],
@@ -78,22 +91,32 @@ export class BasePermissionService<
78
91
  Dto['UpdatePermissionDtoMapper'],
79
92
  Entities['UpdatePermissionDtoMapper']
80
93
  >;
81
- RoleDtoMapper: RequestDtoMapperConstructor<
94
+ RoleEntityMapper: RequestDtoMapperConstructor<
82
95
  SchemaValidator,
83
- Dto['RoleDtoMapper'],
84
- Entities['RoleDtoMapper']
96
+ Dto['RoleEntityMapper'],
97
+ Entities['RoleEntityMapper']
85
98
  >;
99
+ },
100
+ options?: {
101
+ telemetry?: TelemetryOptions;
86
102
  }
87
103
  ) {
88
- this.#mapperss = transformIntoInternalDtoMapper(mapperss, schemaValidator);
104
+ this.#mappers = transformIntoInternalDtoMapper(mappers, schemaValidator);
105
+ this.evaluatedTelemetryOptions = options?.telemetry
106
+ ? evaluateTelemetryOptions(options.telemetry).enabled
107
+ : {
108
+ logging: false,
109
+ metrics: false,
110
+ tracing: false
111
+ };
89
112
  }
90
113
 
91
114
  // start: global helper functions
92
115
  private async updateRolesWithPermissions(
93
- roles: Entities['RoleDtoMapper'][],
116
+ roles: Entities['RoleEntityMapper'][],
94
117
  permissions: Entities['PermissionDtoMapper'][]
95
- ): Promise<Entities['RoleDtoMapper'][]> {
96
- return await Promise.all(
118
+ ): Promise<Entities['RoleEntityMapper'][]> {
119
+ return Promise.all(
97
120
  roles.map(async (role) => {
98
121
  permissions.forEach((permission) => role.permissions.add(permission));
99
122
  return role;
@@ -102,10 +125,10 @@ export class BasePermissionService<
102
125
  }
103
126
 
104
127
  private async removePermissionsFromRoles(
105
- roles: Entities['RoleDtoMapper'][],
128
+ roles: Entities['RoleEntityMapper'][],
106
129
  permissions: Entities['PermissionDtoMapper'][]
107
- ): Promise<Entities['RoleDtoMapper'][]> {
108
- return await Promise.all(
130
+ ): Promise<Entities['RoleEntityMapper'][]> {
131
+ return Promise.all(
109
132
  roles.map(async (role) => {
110
133
  permissions.forEach((permission) =>
111
134
  role.permissions.remove(permission)
@@ -118,14 +141,19 @@ export class BasePermissionService<
118
141
  private async getBatchRoles(
119
142
  roleIds?: IdsDto,
120
143
  em?: EntityManager
121
- ): Promise<Entities['RoleDtoMapper'][]> {
144
+ ): Promise<Entities['RoleEntityMapper'][]> {
122
145
  return roleIds
123
- ? (await this.roleServiceFactory().getBatchRoles(roleIds, em)).map(
124
- (role) => {
125
- return (em ?? this.em).merge(
126
- this.#mapperss.RoleDtoMapper.deserializeDtoToEntity(role)
127
- );
128
- }
146
+ ? await Promise.all(
147
+ (await this.roleServiceFactory().getBatchRoles(roleIds, em)).map(
148
+ async (role) => {
149
+ return (em ?? this.em).merge(
150
+ await this.#mappers.RoleEntityMapper.deserializeDtoToEntity(
151
+ role,
152
+ em ?? this.em
153
+ )
154
+ );
155
+ }
156
+ )
129
157
  )
130
158
  : [];
131
159
  }
@@ -137,12 +165,12 @@ export class BasePermissionService<
137
165
  addToRoles
138
166
  }: {
139
167
  permission: Entities['PermissionDtoMapper'];
140
- addToRoles: Entities['RoleDtoMapper'][];
168
+ addToRoles: Entities['RoleEntityMapper'][];
141
169
  }): Promise<{
142
170
  permission: Entities['PermissionDtoMapper'];
143
- roles: Entities['RoleDtoMapper'][];
171
+ roles: Entities['RoleEntityMapper'][];
144
172
  }> {
145
- let roles: Entities['RoleDtoMapper'][] = [];
173
+ let roles: Entities['RoleEntityMapper'][] = [];
146
174
  if (addToRoles) {
147
175
  roles = await this.updateRolesWithPermissions(addToRoles, [permission]);
148
176
  }
@@ -155,12 +183,13 @@ export class BasePermissionService<
155
183
  em?: EntityManager
156
184
  ): Promise<{
157
185
  permission: Entities['PermissionDtoMapper'];
158
- addToRoles: Entities['RoleDtoMapper'][];
186
+ addToRoles: Entities['RoleEntityMapper'][];
159
187
  }> {
160
188
  return {
161
189
  permission: (em ?? this.em).merge(
162
- this.#mapperss.CreatePermissionDtoMapper.deserializeDtoToEntity(
163
- permissionDto
190
+ await this.#mappers.CreatePermissionDtoMapper.deserializeDtoToEntity(
191
+ permissionDto,
192
+ em ?? this.em
164
193
  )
165
194
  ),
166
195
  addToRoles: permissionDto.addToRolesIds
@@ -174,53 +203,72 @@ export class BasePermissionService<
174
203
  createPermissionDto: Dto['CreatePermissionDtoMapper'],
175
204
  em?: EntityManager
176
205
  ): Promise<Dto['PermissionDtoMapper']> {
206
+ if (this.evaluatedTelemetryOptions.logging) {
207
+ this.openTelemetryCollector.info(
208
+ 'Creating permission',
209
+ createPermissionDto
210
+ );
211
+ }
177
212
  const { permission, roles } = await this.createPermissionDto(
178
213
  await this.extractCreatePermissionDtoToEntityData(createPermissionDto, em)
179
214
  );
180
- await (em ?? this.em).transactional(async (innerEm) => {
181
- await innerEm.persist([permission, ...roles]);
182
- });
183
- return this.#mapperss.PermissionDtoMapper.serializeEntityToDto(permission);
215
+
216
+ if (em) {
217
+ await em.persist([permission, ...roles]);
218
+ } else {
219
+ await this.em.persistAndFlush([permission, ...roles]);
220
+ }
221
+
222
+ return this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission);
184
223
  }
185
224
 
186
225
  async createBatchPermissions(
187
226
  permissionDtos: Dto['CreatePermissionDtoMapper'][],
188
227
  em?: EntityManager
189
228
  ): Promise<Dto['PermissionDtoMapper'][]> {
190
- const rolesCache: Record<string, Entities['RoleDtoMapper']> = {};
229
+ if (this.evaluatedTelemetryOptions.logging) {
230
+ this.openTelemetryCollector.info(
231
+ 'Creating batch permissions',
232
+ permissionDtos
233
+ );
234
+ }
235
+ const rolesCache: Record<string, Entities['RoleEntityMapper']> = {};
191
236
  const permissions: Entities['PermissionDtoMapper'][] = [];
192
- await (em ?? this.em).transactional(async (em) => {
193
- permissionDtos.map(async (createPermissionDto) => {
194
- const { permission, roles } = await this.createPermissionDto(
195
- await this.extractCreatePermissionDtoToEntityData(
196
- createPermissionDto,
197
- em
198
- )
199
- );
200
- roles.forEach((role) => {
201
- if (
202
- rolesCache[role.id] &&
203
- role.permissions !== rolesCache[role.id].permissions
204
- ) {
205
- role.permissions.getItems().forEach((permission) => {
206
- if (!rolesCache[role.id].permissions.contains(permission)) {
207
- rolesCache[role.id].permissions.add(permission);
208
- }
209
- });
210
- } else {
211
- rolesCache[role.id] = role;
212
- }
213
- });
214
- permissions.push(permission);
237
+ permissionDtos.map(async (createPermissionDto) => {
238
+ const { permission, roles } = await this.createPermissionDto(
239
+ await this.extractCreatePermissionDtoToEntityData(
240
+ createPermissionDto,
241
+ em
242
+ )
243
+ );
244
+ roles.forEach((role) => {
245
+ if (
246
+ rolesCache[role.id] &&
247
+ role.permissions !== rolesCache[role.id].permissions
248
+ ) {
249
+ role.permissions.getItems().forEach((permission) => {
250
+ if (!rolesCache[role.id].permissions.contains(permission)) {
251
+ rolesCache[role.id].permissions.add(permission);
252
+ }
253
+ });
254
+ } else {
255
+ rolesCache[role.id] = role;
256
+ }
215
257
  });
216
- await (em ?? this.em).persist([
217
- ...permissions,
218
- ...Object.values(rolesCache)
219
- ]);
258
+ permissions.push(permission);
220
259
  });
260
+ const entities = [...permissions, ...Object.values(rolesCache)];
221
261
 
222
- return permissions.map((permission) =>
223
- this.#mapperss.PermissionDtoMapper.serializeEntityToDto(permission)
262
+ if (em) {
263
+ await em.persist(entities);
264
+ } else {
265
+ await this.em.persistAndFlush(entities);
266
+ }
267
+
268
+ return Promise.all(
269
+ permissions.map(async (permission) =>
270
+ this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission)
271
+ )
224
272
  );
225
273
  }
226
274
 
@@ -228,8 +276,11 @@ export class BasePermissionService<
228
276
  idDto: IdDto,
229
277
  em?: EntityManager
230
278
  ): Promise<Dto['PermissionDtoMapper']> {
279
+ if (this.evaluatedTelemetryOptions.logging) {
280
+ this.openTelemetryCollector.info('Getting permission', idDto);
281
+ }
231
282
  const permission = await (em ?? this.em).findOneOrFail('Permission', idDto);
232
- return this.#mapperss.PermissionDtoMapper.serializeEntityToDto(
283
+ return this.#mappers.PermissionDtoMapper.serializeEntityToDto(
233
284
  permission as Entities['PermissionDtoMapper']
234
285
  );
235
286
  }
@@ -238,11 +289,15 @@ export class BasePermissionService<
238
289
  idsDto: IdsDto,
239
290
  em?: EntityManager
240
291
  ): Promise<Dto['PermissionDtoMapper'][]> {
241
- return (await (em ?? this.em).find('Permission', idsDto)).map(
242
- (permission) =>
243
- this.#mapperss.PermissionDtoMapper.serializeEntityToDto(
292
+ if (this.evaluatedTelemetryOptions.logging) {
293
+ this.openTelemetryCollector.info('Getting batch permissions', idsDto);
294
+ }
295
+ return Promise.all(
296
+ (await (em ?? this.em).find('Permission', idsDto)).map((permission) =>
297
+ this.#mappers.PermissionDtoMapper.serializeEntityToDto(
244
298
  permission as Entities['PermissionDtoMapper']
245
299
  )
300
+ )
246
301
  );
247
302
  }
248
303
 
@@ -252,11 +307,12 @@ export class BasePermissionService<
252
307
  em?: EntityManager
253
308
  ): Promise<{
254
309
  permission: Entities['PermissionDtoMapper'];
255
- roles: Entities['RoleDtoMapper'][];
310
+ roles: Entities['RoleEntityMapper'][];
256
311
  }> => {
257
312
  const permission =
258
- this.#mapperss.UpdatePermissionDtoMapper.deserializeDtoToEntity(
259
- permissionDto
313
+ await this.#mappers.UpdatePermissionDtoMapper.deserializeDtoToEntity(
314
+ permissionDto,
315
+ em ?? this.em
260
316
  );
261
317
  const addToRoles = permissionDto.addToRolesIds
262
318
  ? await this.getBatchRoles({ ids: permissionDto.addToRolesIds }, em)
@@ -265,7 +321,7 @@ export class BasePermissionService<
265
321
  ? await this.getBatchRoles({ ids: permissionDto.removeFromRolesIds }, em)
266
322
  : [];
267
323
 
268
- let roles: Entities['RoleDtoMapper'][] = [];
324
+ let roles: Entities['RoleEntityMapper'][] = [];
269
325
 
270
326
  roles = roles.concat(
271
327
  await this.updateRolesWithPermissions(addToRoles, [permission])
@@ -285,19 +341,32 @@ export class BasePermissionService<
285
341
  permissionDto: Dto['UpdatePermissionDtoMapper'],
286
342
  em?: EntityManager
287
343
  ): Promise<Dto['PermissionDtoMapper']> {
344
+ if (this.evaluatedTelemetryOptions.logging) {
345
+ this.openTelemetryCollector.info('Updating permission', permissionDto);
346
+ }
288
347
  const { permission, roles } = await this.updatePermissionDto(permissionDto);
289
- await (em ?? this.em).upsertMany([permission, ...roles]);
290
- if (!em) {
291
- this.em.flush();
348
+ const entities = await (em ?? this.em).upsertMany([permission, ...roles]);
349
+
350
+ if (em) {
351
+ await em.persist(entities);
352
+ } else {
353
+ await this.em.persistAndFlush(entities);
292
354
  }
293
- return this.#mapperss.PermissionDtoMapper.serializeEntityToDto(permission);
355
+
356
+ return this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission);
294
357
  }
295
358
 
296
359
  async updateBatchPermissions(
297
360
  permissionDtos: Dto['UpdatePermissionDtoMapper'][],
298
361
  em?: EntityManager
299
362
  ): Promise<Dto['PermissionDtoMapper'][]> {
300
- const rolesCache: Record<string, Entities['RoleDtoMapper']> = {};
363
+ if (this.evaluatedTelemetryOptions.logging) {
364
+ this.openTelemetryCollector.info(
365
+ 'Updating batch permissions',
366
+ permissionDtos
367
+ );
368
+ }
369
+ const rolesCache: Record<string, Entities['RoleEntityMapper']> = {};
301
370
  const permissions: Entities['PermissionDtoMapper'][] = [];
302
371
  await (em ?? this.em).transactional(async (em) => {
303
372
  permissionDtos.map(async (updatePermissionDto) => {
@@ -319,18 +388,26 @@ export class BasePermissionService<
319
388
  });
320
389
  permissions.push(permission);
321
390
  });
322
- await (em ?? this.em).persist([
323
- ...permissions,
324
- ...Object.values(rolesCache)
325
- ]);
391
+ const entities = [...permissions, ...Object.values(rolesCache)];
392
+
393
+ if (em) {
394
+ await em.persist(entities);
395
+ } else {
396
+ await this.em.persistAndFlush(entities);
397
+ }
326
398
  });
327
399
 
328
- return permissions.map((permission) =>
329
- this.#mapperss.PermissionDtoMapper.serializeEntityToDto(permission)
400
+ return Promise.all(
401
+ permissions.map((permission) =>
402
+ this.#mappers.PermissionDtoMapper.serializeEntityToDto(permission)
403
+ )
330
404
  );
331
405
  }
332
406
 
333
407
  async deletePermission(idDto: IdDto, em?: EntityManager): Promise<void> {
408
+ if (this.evaluatedTelemetryOptions.logging) {
409
+ this.openTelemetryCollector.info('Deleting permission', idDto);
410
+ }
334
411
  await (em ?? this.em).nativeDelete('Permission', idDto);
335
412
  }
336
413
 
@@ -338,6 +415,9 @@ export class BasePermissionService<
338
415
  idsDto: IdsDto,
339
416
  em?: EntityManager
340
417
  ): Promise<void> {
418
+ if (this.evaluatedTelemetryOptions.logging) {
419
+ this.openTelemetryCollector.info('Deleting batch permissions', idsDto);
420
+ }
341
421
  await (em ?? this.em).nativeDelete('Permission', {
342
422
  id: { $in: idsDto.ids }
343
423
  });