@forklaunch/implementation-iam-base 0.1.1 → 0.1.4

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.
Files changed (84) hide show
  1. package/lib/__test__/schemaEquality.test.d.ts +2 -0
  2. package/lib/__test__/schemaEquality.test.d.ts.map +1 -0
  3. package/lib/__test__/schemaEquality.test.js +175 -0
  4. package/{schemas/typebox → lib/eject/schemas/zod}/organization.schema.ts +4 -4
  5. package/{schemas/typebox → lib/eject/schemas/zod}/permission.schema.ts +1 -1
  6. package/{schemas/typebox → lib/eject/schemas/zod}/role.schema.ts +4 -4
  7. package/{schemas/typebox → lib/eject/schemas/zod}/user.schema.ts +4 -4
  8. package/lib/eject/services/services/organization.service.ts +146 -0
  9. package/lib/eject/services/services/permission.service.ts +349 -0
  10. package/lib/eject/services/services/role.service.ts +182 -0
  11. package/lib/eject/services/user.service.ts +225 -0
  12. package/lib/index.d.ts +9 -0
  13. package/lib/index.d.ts.map +1 -0
  14. package/lib/jest.config.d.ts +4 -0
  15. package/lib/jest.config.d.ts.map +1 -0
  16. package/lib/jest.config.js +19 -0
  17. package/lib/schemas/organization.schema.d.ts +58 -0
  18. package/lib/schemas/organization.schema.d.ts.map +1 -0
  19. package/lib/schemas/organization.schema.js +14 -0
  20. package/lib/schemas/permission.schema.d.ts +42 -0
  21. package/lib/schemas/permission.schema.d.ts.map +1 -0
  22. package/lib/schemas/permission.schema.js +14 -0
  23. package/lib/schemas/role.schema.d.ts +42 -0
  24. package/lib/schemas/role.schema.d.ts.map +1 -0
  25. package/lib/schemas/role.schema.js +14 -0
  26. package/lib/schemas/typebox/organization.schema.d.ts +30 -0
  27. package/lib/schemas/typebox/organization.schema.d.ts.map +1 -0
  28. package/lib/schemas/typebox/organization.schema.js +28 -0
  29. package/lib/schemas/typebox/permission.schema.d.ts +20 -0
  30. package/lib/schemas/typebox/permission.schema.d.ts.map +1 -0
  31. package/lib/schemas/typebox/permission.schema.js +20 -0
  32. package/lib/schemas/typebox/role.schema.d.ts +22 -0
  33. package/lib/schemas/typebox/role.schema.d.ts.map +1 -0
  34. package/lib/schemas/typebox/role.schema.js +20 -0
  35. package/lib/schemas/typebox/user.schema.d.ts +37 -0
  36. package/lib/schemas/typebox/user.schema.d.ts.map +1 -0
  37. package/lib/schemas/typebox/user.schema.js +35 -0
  38. package/lib/schemas/user.schema.d.ts +72 -0
  39. package/lib/schemas/user.schema.d.ts.map +1 -0
  40. package/lib/schemas/user.schema.js +14 -0
  41. package/lib/schemas/zod/organization.schema.d.ts +30 -0
  42. package/lib/schemas/zod/organization.schema.d.ts.map +1 -0
  43. package/lib/schemas/zod/organization.schema.js +28 -0
  44. package/lib/schemas/zod/permission.schema.d.ts +20 -0
  45. package/lib/schemas/zod/permission.schema.d.ts.map +1 -0
  46. package/lib/schemas/zod/permission.schema.js +20 -0
  47. package/lib/schemas/zod/role.schema.d.ts +22 -0
  48. package/lib/schemas/zod/role.schema.d.ts.map +1 -0
  49. package/lib/schemas/zod/role.schema.js +20 -0
  50. package/lib/schemas/zod/user.schema.d.ts +37 -0
  51. package/lib/schemas/zod/user.schema.d.ts.map +1 -0
  52. package/lib/schemas/zod/user.schema.js +35 -0
  53. package/lib/services/organization.service.d.ts +44 -0
  54. package/lib/services/organization.service.d.ts.map +1 -0
  55. package/lib/services/organization.service.js +35 -0
  56. package/lib/services/permission.service.d.ts +61 -0
  57. package/lib/services/permission.service.d.ts.map +1 -0
  58. package/lib/services/permission.service.js +159 -0
  59. package/lib/services/role.service.d.ts +48 -0
  60. package/lib/services/role.service.d.ts.map +1 -0
  61. package/lib/services/role.service.js +57 -0
  62. package/lib/services/user.service.d.ts +54 -0
  63. package/lib/services/user.service.d.ts.map +1 -0
  64. package/lib/services/user.service.js +85 -0
  65. package/lib/tsconfig.tsbuildinfo +1 -0
  66. package/lib/vitest.config.d.ts +3 -0
  67. package/lib/vitest.config.d.ts.map +1 -0
  68. package/lib/vitest.config.js +7 -0
  69. package/package.json +6 -12
  70. package/__test__/schemaEquality.test.ts +0 -293
  71. package/schemas/organization.schema.ts +0 -28
  72. package/schemas/permission.schema.ts +0 -28
  73. package/schemas/role.schema.ts +0 -28
  74. package/schemas/user.schema.ts +0 -28
  75. package/tsconfig.json +0 -7
  76. /package/{schemas/zod → lib/eject/schemas}/organization.schema.ts +0 -0
  77. /package/{schemas/zod → lib/eject/schemas}/permission.schema.ts +0 -0
  78. /package/{schemas/zod → lib/eject/schemas}/role.schema.ts +0 -0
  79. /package/{schemas/zod → lib/eject/schemas}/user.schema.ts +0 -0
  80. /package/{services → lib/eject/services}/organization.service.ts +0 -0
  81. /package/{services → lib/eject/services}/permission.service.ts +0 -0
  82. /package/{services → lib/eject/services}/role.service.ts +0 -0
  83. /package/{services → lib/eject/services/services}/user.service.ts +0 -0
  84. /package/{index.ts → lib/index.js} +0 -0
@@ -0,0 +1,225 @@
1
+ import {
2
+ CreateUserDto,
3
+ RoleService,
4
+ UpdateUserDto,
5
+ UserDto,
6
+ UserService
7
+ } from '@forklaunch/interfaces-iam';
8
+ import {
9
+ MetricsDefinition,
10
+ OpenTelemetryCollector
11
+ } from '@forklaunch/core/http';
12
+
13
+ import { OrganizationService } from '@forklaunch/interfaces-iam';
14
+ import { IdDto, IdsDto, InstanceTypeRecord } from '@forklaunch/common';
15
+ import {
16
+ InternalDtoMapper,
17
+ RequestDtoMapperConstructor,
18
+ ResponseDtoMapperConstructor,
19
+ transformIntoInternalDtoMapper
20
+ } from '@forklaunch/core/dtoMapper';
21
+ import { MapNestedDtoArraysToCollections } from '@forklaunch/core/services';
22
+ import { AnySchemaValidator } from '@forklaunch/validator';
23
+ import { EntityManager } from '@mikro-orm/core';
24
+
25
+ export class BaseUserService<
26
+ SchemaValidator extends AnySchemaValidator,
27
+ OrganizationStatus,
28
+ Metrics extends MetricsDefinition = MetricsDefinition,
29
+ Dto extends {
30
+ UserDtoMapper: UserDto;
31
+ CreateUserDtoMapper: CreateUserDto;
32
+ UpdateUserDtoMapper: UpdateUserDto;
33
+ } = {
34
+ UserDtoMapper: UserDto;
35
+ CreateUserDtoMapper: CreateUserDto;
36
+ UpdateUserDtoMapper: UpdateUserDto;
37
+ },
38
+ Entities extends {
39
+ UserDtoMapper: MapNestedDtoArraysToCollections<UserDto, 'roles'>;
40
+ CreateUserDtoMapper: MapNestedDtoArraysToCollections<UserDto, 'roles'>;
41
+ UpdateUserDtoMapper: MapNestedDtoArraysToCollections<UserDto, 'roles'>;
42
+ } = {
43
+ UserDtoMapper: MapNestedDtoArraysToCollections<UserDto, 'roles'>;
44
+ CreateUserDtoMapper: MapNestedDtoArraysToCollections<UserDto, 'roles'>;
45
+ UpdateUserDtoMapper: MapNestedDtoArraysToCollections<UserDto, 'roles'>;
46
+ }
47
+ > implements UserService
48
+ {
49
+ #dtoMappers: InternalDtoMapper<
50
+ InstanceTypeRecord<typeof this.dtoMappers>,
51
+ Entities,
52
+ Dto
53
+ >;
54
+
55
+ constructor(
56
+ public em: EntityManager,
57
+ protected passwordEncryptionPublicKeyPath: string,
58
+ protected roleServiceFactory: () => RoleService,
59
+ protected organizationServiceFactory: () => OrganizationService<OrganizationStatus>,
60
+ protected openTelemetryCollector: OpenTelemetryCollector<Metrics>,
61
+ protected schemaValidator: SchemaValidator,
62
+ protected dtoMappers: {
63
+ UserDtoMapper: ResponseDtoMapperConstructor<
64
+ SchemaValidator,
65
+ Dto['UserDtoMapper'],
66
+ Entities['UserDtoMapper']
67
+ >;
68
+ CreateUserDtoMapper: RequestDtoMapperConstructor<
69
+ SchemaValidator,
70
+ Dto['CreateUserDtoMapper'],
71
+ Entities['CreateUserDtoMapper'],
72
+ (
73
+ dto: never,
74
+ passwordEncryptionPublicKeyPath: string
75
+ ) => Entities['UpdateUserDtoMapper']
76
+ >;
77
+ UpdateUserDtoMapper: RequestDtoMapperConstructor<
78
+ SchemaValidator,
79
+ Dto['UpdateUserDtoMapper'],
80
+ Entities['UpdateUserDtoMapper'],
81
+ (
82
+ dto: never,
83
+ passwordEncryptionPublicKeyPath: string
84
+ ) => Entities['UpdateUserDtoMapper']
85
+ >;
86
+ }
87
+ ) {
88
+ this.#dtoMappers = transformIntoInternalDtoMapper(
89
+ dtoMappers,
90
+ schemaValidator
91
+ );
92
+ }
93
+
94
+ async createUser(
95
+ userDto: Dto['CreateUserDtoMapper'],
96
+ em?: EntityManager
97
+ ): Promise<Dto['UserDtoMapper']> {
98
+ const user =
99
+ await this.#dtoMappers.CreateUserDtoMapper.deserializeDtoToEntity(
100
+ userDto,
101
+ this.passwordEncryptionPublicKeyPath
102
+ );
103
+ ((await em) ?? this.em).transactional(async (em) => {
104
+ await em.persist(user);
105
+ });
106
+ return this.#dtoMappers.UserDtoMapper.serializeEntityToDto(user);
107
+ }
108
+
109
+ async createBatchUsers(
110
+ userDtos: Dto['CreateUserDtoMapper'][],
111
+ em?: EntityManager
112
+ ): Promise<Dto['UserDtoMapper'][]> {
113
+ const users = await Promise.all(
114
+ userDtos.map(async (createUserDto) =>
115
+ this.#dtoMappers.CreateUserDtoMapper.deserializeDtoToEntity(
116
+ createUserDto,
117
+ this.passwordEncryptionPublicKeyPath
118
+ )
119
+ )
120
+ );
121
+ await (em ?? this.em).transactional(async (em) => {
122
+ await em.persist(users);
123
+ });
124
+
125
+ return users.map((user) =>
126
+ this.#dtoMappers.UserDtoMapper.serializeEntityToDto(user)
127
+ );
128
+ }
129
+
130
+ async getUser(
131
+ idDto: IdDto,
132
+ em?: EntityManager
133
+ ): Promise<Dto['UserDtoMapper']> {
134
+ const user = await (em ?? this.em).findOneOrFail('User', idDto, {
135
+ populate: ['id', '*']
136
+ });
137
+ return this.#dtoMappers.UserDtoMapper.serializeEntityToDto(
138
+ user as Entities['UserDtoMapper']
139
+ );
140
+ }
141
+
142
+ async getBatchUsers(
143
+ idsDto: IdsDto,
144
+ em?: EntityManager
145
+ ): Promise<Dto['UserDtoMapper'][]> {
146
+ return (
147
+ await (em ?? this.em).find('User', idsDto, {
148
+ populate: ['id', '*']
149
+ })
150
+ ).map((user) =>
151
+ this.#dtoMappers.UserDtoMapper.serializeEntityToDto(
152
+ user as Entities['UserDtoMapper']
153
+ )
154
+ );
155
+ }
156
+
157
+ async updateUser(
158
+ userDto: Dto['UpdateUserDtoMapper'],
159
+ em?: EntityManager
160
+ ): Promise<Dto['UserDtoMapper']> {
161
+ let user = this.#dtoMappers.UpdateUserDtoMapper.deserializeDtoToEntity(
162
+ userDto,
163
+ this.passwordEncryptionPublicKeyPath
164
+ );
165
+ await (em ?? this.em).transactional(async (localEm) => {
166
+ user = await localEm.upsert(user);
167
+ });
168
+ return this.#dtoMappers.UserDtoMapper.serializeEntityToDto(user);
169
+ }
170
+
171
+ async updateBatchUsers(
172
+ userDtos: UpdateUserDto[],
173
+ em?: EntityManager
174
+ ): Promise<Dto['UserDtoMapper'][]> {
175
+ let users = await Promise.all(
176
+ userDtos.map(async (updateUserDto) =>
177
+ this.#dtoMappers.UpdateUserDtoMapper.deserializeDtoToEntity(
178
+ updateUserDto,
179
+ this.passwordEncryptionPublicKeyPath
180
+ )
181
+ )
182
+ );
183
+ await (em ?? this.em).transactional(async (localEm) => {
184
+ users = await localEm.upsertMany(users);
185
+ });
186
+ return users.map((user) =>
187
+ this.#dtoMappers.UserDtoMapper.serializeEntityToDto(user)
188
+ );
189
+ }
190
+
191
+ async deleteUser(idDto: IdDto, em?: EntityManager): Promise<void> {
192
+ const entityManager = em || this.em;
193
+ await entityManager.nativeDelete('User', idDto);
194
+ }
195
+
196
+ async deleteBatchUsers(idsDto: IdsDto, em?: EntityManager): Promise<void> {
197
+ const entityManager = em || this.em;
198
+ await entityManager.nativeDelete('User', idsDto);
199
+ }
200
+
201
+ async verifyHasRole(idDto: IdDto, roleId: string): Promise<void> {
202
+ const user = await this.getUser(idDto);
203
+ if (
204
+ user.roles.filter((role) => {
205
+ return roleId == role.id;
206
+ }).length === 0
207
+ ) {
208
+ throw new Error(`User ${idDto.id} does not have role ${roleId}`);
209
+ }
210
+ }
211
+
212
+ async verifyHasPermission(idDto: IdDto, permissionId: string): Promise<void> {
213
+ const user = await this.getUser(idDto);
214
+ if (
215
+ user.roles
216
+ .map((role) => role.permissions.map((permission) => permission.id))
217
+ .flat()
218
+ .filter((id) => id == permissionId).length === 0
219
+ ) {
220
+ throw new Error(
221
+ `User ${idDto.id} does not have permission ${permissionId}`
222
+ );
223
+ }
224
+ }
225
+ }
package/lib/index.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ export * from './schemas/organization.schema';
2
+ export * from './schemas/permission.schema';
3
+ export * from './schemas/role.schema';
4
+ export * from './schemas/user.schema';
5
+ export * from './services/organization.service';
6
+ export * from './services/permission.service';
7
+ export * from './services/role.service';
8
+ export * from './services/user.service';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { JestConfigWithTsJest } from 'ts-jest';
2
+ declare const jestConfig: JestConfigWithTsJest;
3
+ export default jestConfig;
4
+ //# sourceMappingURL=jest.config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jest.config.d.ts","sourceRoot":"","sources":["../jest.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAEpD,QAAA,MAAM,UAAU,EAAE,oBAiBjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -0,0 +1,19 @@
1
+ const jestConfig = {
2
+ preset: 'ts-jest/presets/default-esm', // or other ESM presets
3
+ moduleNameMapper: {
4
+ '^(\\.{1,2}/.*)\\.js$': '$1'
5
+ },
6
+ transform: {
7
+ // '^.+\\.[tj]sx?$' to process ts,js,tsx,jsx with `ts-jest`
8
+ // '^.+\\.m?[tj]sx?$' to process ts,js,tsx,jsx,mts,mjs,mtsx,mjsx with `ts-jest`
9
+ '^.+\\.[tj]sx?$': [
10
+ 'ts-jest',
11
+ {
12
+ useESM: true
13
+ }
14
+ ],
15
+ '^.+\\.js$': 'babel-jest'
16
+ },
17
+ testPathIgnorePatterns: ['.*dist/', '.*node_modules/']
18
+ };
19
+ export default jestConfig;