@lenne.tech/nest-server 8.0.2 → 8.3.0

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 (166) hide show
  1. package/dist/config.env.js +3 -2
  2. package/dist/config.env.js.map +1 -1
  3. package/dist/core/common/args/pagination.args.js +1 -1
  4. package/dist/core/common/args/pagination.args.js.map +1 -1
  5. package/dist/core/common/decorators/restricted.decorator.d.ts +3 -0
  6. package/dist/core/common/decorators/restricted.decorator.js +14 -8
  7. package/dist/core/common/decorators/restricted.decorator.js.map +1 -1
  8. package/dist/core/common/enums/role.enum.d.ts +3 -2
  9. package/dist/core/common/enums/role.enum.js +3 -2
  10. package/dist/core/common/enums/role.enum.js.map +1 -1
  11. package/dist/core/common/helpers/config.helper.d.ts +2 -1
  12. package/dist/core/common/helpers/config.helper.js +11 -7
  13. package/dist/core/common/helpers/config.helper.js.map +1 -1
  14. package/dist/core/common/helpers/context.helper.d.ts +7 -1
  15. package/dist/core/common/helpers/context.helper.js +33 -29
  16. package/dist/core/common/helpers/context.helper.js.map +1 -1
  17. package/dist/core/common/helpers/db.helper.d.ts +37 -0
  18. package/dist/core/common/helpers/db.helper.js +356 -0
  19. package/dist/core/common/helpers/db.helper.js.map +1 -0
  20. package/dist/core/common/helpers/file.helper.d.ts +8 -1
  21. package/dist/core/common/helpers/file.helper.js +43 -31
  22. package/dist/core/common/helpers/file.helper.js.map +1 -1
  23. package/dist/core/common/helpers/filter.helper.d.ts +3 -0
  24. package/dist/core/common/helpers/filter.helper.js +93 -81
  25. package/dist/core/common/helpers/filter.helper.js.map +1 -1
  26. package/dist/core/common/helpers/graphql.helper.d.ts +24 -1
  27. package/dist/core/common/helpers/graphql.helper.js +144 -96
  28. package/dist/core/common/helpers/graphql.helper.js.map +1 -1
  29. package/dist/core/common/helpers/input.helper.d.ts +42 -4
  30. package/dist/core/common/helpers/input.helper.js +256 -97
  31. package/dist/core/common/helpers/input.helper.js.map +1 -1
  32. package/dist/core/common/helpers/model.helper.d.ts +11 -0
  33. package/dist/core/common/helpers/model.helper.js +41 -29
  34. package/dist/core/common/helpers/model.helper.js.map +1 -1
  35. package/dist/core/common/helpers/service.helper.d.ts +21 -1
  36. package/dist/core/common/helpers/service.helper.js +80 -72
  37. package/dist/core/common/helpers/service.helper.js.map +1 -1
  38. package/dist/core/common/inputs/combined-filter.input.js +1 -1
  39. package/dist/core/common/inputs/combined-filter.input.js.map +1 -1
  40. package/dist/core/common/inputs/core-input.input.js +1 -1
  41. package/dist/core/common/inputs/core-input.input.js.map +1 -1
  42. package/dist/core/common/interceptors/check-response.interceptor.js +1 -1
  43. package/dist/core/common/interceptors/check-response.interceptor.js.map +1 -1
  44. package/dist/core/common/interfaces/resolve-selector.interface.d.ts +5 -0
  45. package/dist/core/common/interfaces/resolve-selector.interface.js +3 -0
  46. package/dist/core/common/interfaces/resolve-selector.interface.js.map +1 -0
  47. package/dist/core/common/interfaces/service-options.interface.d.ts +36 -0
  48. package/dist/core/common/interfaces/service-options.interface.js +3 -0
  49. package/dist/core/common/interfaces/service-options.interface.js.map +1 -0
  50. package/dist/core/common/models/core-model.model.d.ts +5 -1
  51. package/dist/core/common/models/core-model.model.js +1 -1
  52. package/dist/core/common/models/core-model.model.js.map +1 -1
  53. package/dist/core/common/pipes/check-input.pipe.js +2 -2
  54. package/dist/core/common/pipes/check-input.pipe.js.map +1 -1
  55. package/dist/core/common/pipes/map-and-validate.pipe.js +1 -1
  56. package/dist/core/common/pipes/map-and-validate.pipe.js.map +1 -1
  57. package/dist/core/common/services/crud.service.d.ts +13 -0
  58. package/dist/core/common/services/crud.service.js +57 -0
  59. package/dist/core/common/services/crud.service.js.map +1 -0
  60. package/dist/core/common/services/email.service.js +8 -8
  61. package/dist/core/common/services/email.service.js.map +1 -1
  62. package/dist/core/common/services/module.service.d.ts +40 -0
  63. package/dist/core/common/services/module.service.js +80 -0
  64. package/dist/core/common/services/module.service.js.map +1 -0
  65. package/dist/core/common/types/core-model-constructor.type.d.ts +21 -0
  66. package/dist/core/common/types/core-model-constructor.type.js +3 -0
  67. package/dist/core/common/types/core-model-constructor.type.js.map +1 -0
  68. package/dist/core/common/types/field-selection.type.d.ts +4 -0
  69. package/dist/core/common/types/field-selection.type.js +3 -0
  70. package/dist/core/common/types/field-selection.type.js.map +1 -0
  71. package/dist/core/common/types/ids.type.d.ts +8 -0
  72. package/dist/core/common/types/ids.type.js +3 -0
  73. package/dist/core/common/types/ids.type.js.map +1 -0
  74. package/dist/core/common/types/string-or-object-id.type.d.ts +2 -0
  75. package/dist/core/common/types/string-or-object-id.type.js +3 -0
  76. package/dist/core/common/types/string-or-object-id.type.js.map +1 -0
  77. package/dist/core/modules/auth/core-auth.resolver.d.ts +2 -1
  78. package/dist/core/modules/auth/core-auth.resolver.js +4 -3
  79. package/dist/core/modules/auth/core-auth.resolver.js.map +1 -1
  80. package/dist/core/modules/auth/guards/roles.guard.js +1 -2
  81. package/dist/core/modules/auth/guards/roles.guard.js.map +1 -1
  82. package/dist/core/modules/auth/services/core-auth-user.service.d.ts +3 -1
  83. package/dist/core/modules/auth/services/core-auth-user.service.js.map +1 -1
  84. package/dist/core/modules/auth/services/core-auth.service.d.ts +2 -1
  85. package/dist/core/modules/auth/services/core-auth.service.js +6 -4
  86. package/dist/core/modules/auth/services/core-auth.service.js.map +1 -1
  87. package/dist/core/modules/user/core-user.model.js +1 -1
  88. package/dist/core/modules/user/core-user.model.js.map +1 -1
  89. package/dist/core/modules/user/core-user.service.d.ts +16 -25
  90. package/dist/core/modules/user/core-user.service.js +69 -90
  91. package/dist/core/modules/user/core-user.service.js.map +1 -1
  92. package/dist/core.module.js +1 -1
  93. package/dist/core.module.js.map +1 -1
  94. package/dist/index.d.ts +9 -1
  95. package/dist/index.js +9 -1
  96. package/dist/index.js.map +1 -1
  97. package/dist/server/modules/auth/auth.resolver.d.ts +2 -1
  98. package/dist/server/modules/auth/auth.resolver.js +4 -3
  99. package/dist/server/modules/auth/auth.resolver.js.map +1 -1
  100. package/dist/server/modules/file/file.controller.js +1 -1
  101. package/dist/server/modules/file/file.controller.js.map +1 -1
  102. package/dist/server/modules/user/avatar.controller.js +2 -2
  103. package/dist/server/modules/user/avatar.controller.js.map +1 -1
  104. package/dist/server/modules/user/user.model.d.ts +2 -1
  105. package/dist/server/modules/user/user.module.js +7 -3
  106. package/dist/server/modules/user/user.module.js.map +1 -1
  107. package/dist/server/modules/user/user.resolver.d.ts +8 -7
  108. package/dist/server/modules/user/user.resolver.js +85 -49
  109. package/dist/server/modules/user/user.resolver.js.map +1 -1
  110. package/dist/server/modules/user/user.service.d.ts +9 -18
  111. package/dist/server/modules/user/user.service.js +23 -30
  112. package/dist/server/modules/user/user.service.js.map +1 -1
  113. package/dist/test/test.helper.d.ts +1 -2
  114. package/dist/test/test.helper.js +1 -16
  115. package/dist/test/test.helper.js.map +1 -1
  116. package/dist/tsconfig.build.tsbuildinfo +1 -1
  117. package/package.json +58 -59
  118. package/src/config.env.ts +3 -2
  119. package/src/core/common/args/pagination.args.ts +2 -2
  120. package/src/core/common/decorators/restricted.decorator.ts +24 -12
  121. package/src/core/common/enums/role.enum.ts +23 -5
  122. package/src/core/common/helpers/config.helper.ts +26 -6
  123. package/src/core/common/helpers/context.helper.ts +42 -33
  124. package/src/core/common/helpers/db.helper.ts +595 -0
  125. package/src/core/common/helpers/file.helper.ts +76 -49
  126. package/src/core/common/helpers/filter.helper.ts +119 -96
  127. package/src/core/common/helpers/graphql.helper.ts +219 -117
  128. package/src/core/common/helpers/input.helper.ts +349 -108
  129. package/src/core/common/helpers/model.helper.ts +102 -57
  130. package/src/core/common/helpers/service.helper.ts +149 -117
  131. package/src/core/common/inputs/combined-filter.input.ts +2 -2
  132. package/src/core/common/inputs/core-input.input.ts +2 -2
  133. package/src/core/common/interceptors/check-response.interceptor.ts +2 -2
  134. package/src/core/common/interfaces/resolve-selector.interface.ts +9 -0
  135. package/src/core/common/interfaces/service-options.interface.ts +71 -0
  136. package/src/core/common/models/core-model.model.ts +7 -3
  137. package/src/core/common/pipes/check-input.pipe.ts +4 -4
  138. package/src/core/common/pipes/map-and-validate.pipe.ts +2 -2
  139. package/src/core/common/services/crud.service.ts +100 -0
  140. package/src/core/common/services/email.service.ts +9 -9
  141. package/src/core/common/services/module.service.ts +188 -0
  142. package/src/core/common/types/core-model-constructor.type.ts +30 -0
  143. package/src/core/common/types/field-selection.type.ts +8 -0
  144. package/src/core/common/types/ids.type.ts +7 -0
  145. package/src/core/common/types/string-or-object-id.type.ts +3 -0
  146. package/src/core/modules/auth/core-auth.module.ts +1 -1
  147. package/src/core/modules/auth/core-auth.resolver.ts +8 -3
  148. package/src/core/modules/auth/guards/roles.guard.ts +5 -7
  149. package/src/core/modules/auth/services/core-auth-user.service.ts +7 -1
  150. package/src/core/modules/auth/services/core-auth.service.ts +14 -4
  151. package/src/core/modules/user/core-user.model.ts +2 -1
  152. package/src/core/modules/user/core-user.service.ts +115 -185
  153. package/src/core.module.ts +2 -2
  154. package/src/index.ts +9 -1
  155. package/src/main.ts +1 -1
  156. package/src/server/modules/auth/auth.resolver.ts +8 -3
  157. package/src/server/modules/file/file.controller.ts +2 -2
  158. package/src/server/modules/user/avatar.controller.ts +3 -3
  159. package/src/server/modules/user/user.module.ts +7 -3
  160. package/src/server/modules/user/user.resolver.ts +74 -43
  161. package/src/server/modules/user/user.service.ts +30 -53
  162. package/src/test/test.helper.ts +31 -30
  163. package/dist/core/modules/user/core-basic-user.service.d.ts +0 -17
  164. package/dist/core/modules/user/core-basic-user.service.js +0 -73
  165. package/dist/core/modules/user/core-basic-user.service.js.map +0 -1
  166. package/src/core/modules/user/core-basic-user.service.ts +0 -138
@@ -1,68 +1,45 @@
1
- import { BadRequestException } from '@nestjs/common';
1
+ import { BadRequestException, UnauthorizedException } from '@nestjs/common';
2
2
  import { plainToInstance } from 'class-transformer';
3
3
  import { validate } from 'class-validator';
4
4
  import * as _ from 'lodash';
5
5
  import { checkRestricted } from '../decorators/restricted.decorator';
6
+ import { RoleEnum } from '../enums/role.enum';
7
+ import { IdsType } from '../types/ids.type';
8
+ import { equalIds, getStringIds } from './db.helper';
6
9
 
7
10
  /**
8
11
  * Helper class for inputs
12
+ * @deprecated use functions directly
9
13
  */
10
- export class InputHelper {
14
+ export default class InputHelper {
11
15
  /**
12
16
  * Check input
13
17
  */
14
18
  public static async check(
15
19
  value: any,
16
20
  user: { id: any; hasRole: (roles: string[]) => boolean },
17
- metatype?
21
+ options?: { creator?: IdsType; metatype?: any; ownerIds?: IdsType; roles?: string | string[] }
18
22
  ): Promise<any> {
19
- // Return value if it is only a basic type
20
- if (typeof value !== 'object' || !metatype || this.isBasicType(metatype)) {
21
- return value;
22
- }
23
-
24
- // Convert to metatype
25
- if (!(value instanceof metatype)) {
26
- if ((metatype as any)?.map) {
27
- value = (metatype as any)?.map(value);
28
- } else {
29
- value = plainToInstance(metatype, value);
30
- }
31
- }
32
-
33
- // Validate
34
- const errors = await validate(value);
35
- if (errors.length > 0) {
36
- throw new BadRequestException('Validation failed');
37
- }
38
-
39
- // Remove restricted values if roles are missing
40
- value = checkRestricted(value, user);
41
- return value;
23
+ return check(value, user, options);
42
24
  }
43
25
 
44
26
  // Standard error function
45
- public static errorFunction(caller: (...params) => any) {
46
- const err = new Error('Required parameter is missing or invalid');
47
- Error.captureStackTrace(err, caller);
48
- throw err;
27
+ public static errorFunction(caller: (...params) => any, message = 'Required parameter is missing or invalid') {
28
+ return errorFunction(caller, message);
49
29
  }
50
30
 
51
31
  /**
52
32
  * Check if parameter is an array
53
33
  */
54
- public static isArray(parameter: any, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
55
- return parameter !== null && typeof parameter !== 'undefined' && parameter.constructor === Array
56
- ? true
57
- : falseFunction(InputHelper.isArray);
34
+ public static isArray(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
35
+ return isArray(parameter, falseFunction);
58
36
  }
59
37
 
60
38
  /**
61
39
  * Checks if it is a basic type
62
40
  */
63
- public static isBasicType(metatype: any, falseFunction: (...params) => any = InputHelper.returnFalse): boolean {
64
- const types = [String, Boolean, Number, Array, Object, Buffer, ArrayBuffer];
65
- return types.includes(metatype) ? true : falseFunction(InputHelper.isBasicType);
41
+ public static isBasicType(metatype: any, falseFunction: (...params) => any = returnFalse): boolean {
42
+ return isBasicType(metatype, falseFunction);
66
43
  }
67
44
 
68
45
  /**
@@ -72,57 +49,44 @@ export class InputHelper {
72
49
  parameter: number,
73
50
  min: number,
74
51
  max: number,
75
- falseFunction: (...params) => any = InputHelper.errorFunction
52
+ falseFunction: (...params) => any = errorFunction
76
53
  ): boolean {
77
- return typeof parameter === 'number' && parameter > min && parameter < max
78
- ? true
79
- : falseFunction(InputHelper.isBetween);
54
+ return isBetween(parameter, min, max, falseFunction);
80
55
  }
81
56
 
82
57
  /**
83
58
  * Check if parameter is a Date
84
59
  */
85
- public static isDate(parameter: Date, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
86
- return parameter instanceof Date ? true : falseFunction(InputHelper.isDate);
60
+ public static isDate(parameter: Date, falseFunction: (...params) => any = errorFunction): boolean {
61
+ return isDate(parameter, falseFunction);
87
62
  }
88
63
 
89
64
  /**
90
65
  * Check if parameter is a valid email address
91
66
  */
92
- public static isEmail(parameter: string, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
93
- const regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
94
- return regex.test(parameter) ? true : falseFunction(InputHelper.isEmail);
67
+ public static isEmail(parameter: string, falseFunction: (...params) => any = errorFunction): boolean {
68
+ return isEmail(parameter, falseFunction);
95
69
  }
96
70
 
97
71
  /**
98
72
  * Check whether the parameter can be converted to false
99
73
  */
100
- public static isFalse(parameter: any, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
101
- return !parameter ? true : falseFunction(InputHelper.isFalse);
74
+ public static isFalse(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
75
+ return isFalse(parameter, falseFunction);
102
76
  }
103
77
 
104
78
  /**
105
79
  * Check if parameter is a valid file
106
80
  */
107
- public static isFile(parameter: any, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
108
- return parameter !== null &&
109
- typeof parameter !== 'undefined' &&
110
- parameter.name &&
111
- parameter.path &&
112
- parameter.type &&
113
- parameter.size > 0
114
- ? true
115
- : falseFunction(InputHelper.isFile);
81
+ public static isFile(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
82
+ return isFile(parameter, falseFunction);
116
83
  }
117
84
 
118
85
  /**
119
86
  * Check if parameter is a function
120
87
  */
121
- public static isFunction(
122
- parameter: (...params) => any,
123
- falseFunction: (...params) => any = InputHelper.errorFunction
124
- ): boolean {
125
- return typeof parameter === 'function' ? true : falseFunction(InputHelper.isFunction);
88
+ public static isFunction(parameter: (...params) => any, falseFunction: (...params) => any = errorFunction): boolean {
89
+ return isFunction(parameter, falseFunction);
126
90
  }
127
91
 
128
92
  /**
@@ -131,9 +95,9 @@ export class InputHelper {
131
95
  public static isGreater(
132
96
  parameter: number,
133
97
  compare: number,
134
- falseFunction: (...params) => any = InputHelper.errorFunction
98
+ falseFunction: (...params) => any = errorFunction
135
99
  ): boolean {
136
- return typeof parameter === 'number' && parameter > compare ? true : falseFunction(InputHelper.isGreater);
100
+ return isGreater(parameter, compare, falseFunction);
137
101
  }
138
102
 
139
103
  /**
@@ -142,97 +106,374 @@ export class InputHelper {
142
106
  public static isLower(
143
107
  parameter: number,
144
108
  compare: number,
145
- falseFunction: (...params) => any = InputHelper.errorFunction
109
+ falseFunction: (...params) => any = errorFunction
146
110
  ): boolean {
147
- return typeof parameter === 'number' && parameter < compare ? true : falseFunction(InputHelper.isLower);
111
+ return isLower(parameter, compare, falseFunction);
148
112
  }
149
113
 
150
114
  /**
151
- * Check if parameter is a non empty array
115
+ * Check if parameter is a non-empty array
152
116
  */
153
- public static isNonEmptyArray(
154
- parameter: any,
155
- errorFunction: (...params) => any = InputHelper.errorFunction
156
- ): boolean {
157
- return parameter !== null &&
158
- typeof parameter !== 'undefined' &&
159
- parameter.constructor === Array &&
160
- parameter.length > 0
161
- ? true
162
- : errorFunction(InputHelper.isNonEmptyArray);
117
+ public static isNonEmptyArray(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
118
+ return isNonEmptyString(parameter, errorFunction);
163
119
  }
164
120
 
165
121
  /**
166
122
  * Check if parameter is a non empty object
167
123
  */
168
- public static isNonEmptyObject(
169
- parameter: any,
170
- falseFunction: (...params) => any = InputHelper.errorFunction
171
- ): boolean {
172
- return parameter !== null &&
173
- typeof parameter !== 'undefined' &&
174
- parameter.constructor === Object &&
175
- Object.keys(parameter).length !== 0
176
- ? true
177
- : falseFunction(InputHelper.isNonEmptyObject);
124
+ public static isNonEmptyObject(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
125
+ return isNonEmptyObject(parameter, falseFunction);
178
126
  }
179
127
 
180
128
  /**
181
129
  * Check if parameter is a non empty string
182
130
  */
183
- public static isNonEmptyString(
184
- parameter: string,
185
- falseFunction: (...params) => any = InputHelper.errorFunction
186
- ): boolean {
187
- return typeof parameter === 'string' && parameter.length > 0 ? true : falseFunction(InputHelper.isNonEmptyString);
131
+ public static isNonEmptyString(parameter: string, falseFunction: (...params) => any = errorFunction): boolean {
132
+ return isNonEmptyString(parameter, falseFunction);
188
133
  }
189
134
 
190
135
  /**
191
136
  * Check if parameter is a number
192
137
  */
193
- public static isNumber(parameter: number, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
194
- return typeof parameter === 'number' ? true : falseFunction(InputHelper.isNumber);
138
+ public static isNumber(parameter: number, falseFunction: (...params) => any = errorFunction): boolean {
139
+ return isNumber(parameter, falseFunction);
195
140
  }
196
141
 
197
142
  /**
198
143
  * Check if parameter is an object
199
144
  */
200
- public static isObject(parameter: any, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
201
- return parameter !== null && typeof parameter !== 'undefined' && parameter.constructor === Object
202
- ? true
203
- : falseFunction(InputHelper.isObject);
145
+ public static isObject(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
146
+ return isObject(parameter, falseFunction);
204
147
  }
205
148
 
206
149
  /**
207
150
  * Check whether the parameter can be converted to true
208
151
  */
209
- public static isTrue(parameter: any, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
210
- return !!parameter ? true : falseFunction(InputHelper.isTrue);
152
+ public static isTrue(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
153
+ return isTrue(parameter, falseFunction);
211
154
  }
212
155
 
213
156
  /**
214
157
  * Check if parameter is a string
215
158
  */
216
- public static isString(parameter: string, falseFunction: (...params) => any = InputHelper.errorFunction): boolean {
217
- return typeof parameter === 'string' ? true : falseFunction(InputHelper.isString);
159
+ public static isString(parameter: string, falseFunction: (...params) => any = errorFunction): boolean {
160
+ return isString(parameter, falseFunction);
218
161
  }
219
162
 
220
163
  /**
221
164
  * Alternative for errorFunction
222
165
  */
223
166
  public static returnFalse(): boolean {
224
- return false;
167
+ return returnFalse();
225
168
  }
226
169
 
227
170
  /**
228
171
  * Map values into specific type
172
+ * @deprecated use mapClass function
229
173
  */
230
174
  public static map<T>(values: Partial<T>, ctor: new () => T, cloneDeep = true): T {
231
- const instance = new ctor();
175
+ return mapClass(values, ctor);
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Check input
181
+ */
182
+ export async function check(
183
+ value: any,
184
+ user: { id: any; hasRole: (roles: string[]) => boolean },
185
+ options?: { creator?: IdsType; metatype?: any; ownerIds?: IdsType; roles?: string | string[]; throwError?: boolean }
186
+ ): Promise<any> {
187
+ const config = {
188
+ throwError: true,
189
+ ...options,
190
+ };
191
+
192
+ // Check roles
193
+ if (config.roles?.length && config.throwError) {
194
+ let roles = config.roles;
195
+ if (!Array.isArray(roles)) {
196
+ roles = [roles];
197
+ }
198
+ let valid = false;
199
+ if (roles.includes(RoleEnum.S_USER) && user?.id) {
200
+ valid = true;
201
+ } else if (user.hasRole(roles)) {
202
+ valid = true;
203
+ } else if (roles.includes(RoleEnum.S_CREATOR) && user?.id && equalIds(user.id, config.creator)) {
204
+ valid = true;
205
+ } else if (roles.includes(RoleEnum.S_OWNER) && user?.id && config.ownerIds) {
206
+ let ownerIds: string | string[] = getStringIds(config.ownerIds);
207
+ if (!Array.isArray(ownerIds)) {
208
+ ownerIds = [ownerIds];
209
+ }
210
+ valid = ownerIds.includes(getStringIds(user.id));
211
+ }
212
+ if (!valid) {
213
+ throw new UnauthorizedException('Missing rights');
214
+ }
215
+ }
216
+
217
+ // Return value if it is only a basic type
218
+ if (typeof value !== 'object') {
219
+ return value;
220
+ }
221
+
222
+ // Check array
223
+ if (Array.isArray(value)) {
224
+ for (const [key, item] of Object.entries(value)) {
225
+ value[key] = await check(item, user, config);
226
+ }
227
+ return value;
228
+ }
229
+
230
+ const metatype = config.metatype;
231
+ if (metatype) {
232
+ // Check metatype
233
+ if (isBasicType(metatype)) {
234
+ return value;
235
+ }
236
+
237
+ // Convert to metatype
238
+ if (!(value instanceof metatype)) {
239
+ if ((metatype as any)?.map) {
240
+ value = (metatype as any)?.map(value);
241
+ } else {
242
+ value = plainToInstance(metatype, value);
243
+ }
244
+ }
245
+ }
246
+
247
+ // Validate
248
+ const errors = await validate(value);
249
+ if (errors.length > 0 && config.throwError) {
250
+ throw new BadRequestException('Validation failed');
251
+ }
252
+
253
+ // Remove restricted values if roles are missing
254
+ value = checkRestricted(value, user, config);
255
+ return value;
256
+ }
257
+
258
+ /**
259
+ * Standard error function
260
+ */
261
+ export function errorFunction(caller: (...params) => any, message = 'Required parameter is missing or invalid') {
262
+ const err = new Error(message);
263
+ Error.captureStackTrace(err, caller);
264
+ throw err;
265
+ }
266
+
267
+ /**
268
+ * Check if parameter is an array
269
+ */
270
+ export function isArray(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
271
+ return Array.isArray(parameter) ? true : falseFunction(isArray);
272
+ }
273
+
274
+ /**
275
+ * Checks if it is a basic type
276
+ */
277
+ export function isBasicType(metatype: any, falseFunction: (...params) => any = returnFalse): boolean {
278
+ const types = [String, Boolean, Number, Array, Object, Buffer, ArrayBuffer];
279
+ return types.includes(metatype) ? true : falseFunction(isBasicType);
280
+ }
281
+
282
+ /**
283
+ * Check if parameter is between min and max
284
+ */
285
+ export function isBetween(
286
+ parameter: number,
287
+ min: number,
288
+ max: number,
289
+ falseFunction: (...params) => any = errorFunction
290
+ ): boolean {
291
+ return typeof parameter === 'number' && parameter > min && parameter < max ? true : falseFunction(isBetween);
292
+ }
293
+
294
+ /**
295
+ * Check if parameter is a Date
296
+ */
297
+ export function isDate(parameter: Date, falseFunction: (...params) => any = errorFunction): boolean {
298
+ return parameter instanceof Date ? true : falseFunction(isDate);
299
+ }
232
300
 
233
- return Object.keys(instance).reduce((obj, key) => {
234
- obj[key] = cloneDeep ? _.cloneDeep(values[key]) : values[key];
235
- return obj;
236
- }, instance);
301
+ /**
302
+ * Check if parameter is a valid email address
303
+ */
304
+ export function isEmail(parameter: string, falseFunction: (...params) => any = errorFunction): boolean {
305
+ const regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,})+$/;
306
+ return regex.test(parameter) ? true : falseFunction(isEmail);
307
+ }
308
+
309
+ /**
310
+ * Check whether the parameter can be converted to false
311
+ */
312
+ export function isFalse(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
313
+ return !parameter ? true : falseFunction(isFalse);
314
+ }
315
+
316
+ /**
317
+ * Check if parameter is a valid file
318
+ */
319
+ export function isFile(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
320
+ return parameter !== null &&
321
+ typeof parameter !== 'undefined' &&
322
+ parameter.name &&
323
+ parameter.path &&
324
+ parameter.type &&
325
+ parameter.size > 0
326
+ ? true
327
+ : falseFunction(isFile);
328
+ }
329
+
330
+ /**
331
+ * Check if parameter is a function
332
+ */
333
+ export function isFunction(parameter: (...params) => any, falseFunction: (...params) => any = errorFunction): boolean {
334
+ return typeof parameter === 'function' ? true : falseFunction(isFunction);
335
+ }
336
+
337
+ /**
338
+ * Check if parameter is greater than the compare number
339
+ */
340
+ export function isGreater(
341
+ parameter: number,
342
+ compare: number,
343
+ falseFunction: (...params) => any = errorFunction
344
+ ): boolean {
345
+ return typeof parameter === 'number' && parameter > compare ? true : falseFunction(isGreater);
346
+ }
347
+
348
+ /**
349
+ * Check if parameter is lower than the compare number
350
+ */
351
+ export function isLower(
352
+ parameter: number,
353
+ compare: number,
354
+ falseFunction: (...params) => any = errorFunction
355
+ ): boolean {
356
+ return typeof parameter === 'number' && parameter < compare ? true : falseFunction(isLower);
357
+ }
358
+
359
+ /**
360
+ * Check if parameter is a non empty array
361
+ */
362
+ export function isNonEmptyArray(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
363
+ return parameter !== null &&
364
+ typeof parameter !== 'undefined' &&
365
+ parameter.constructor === Array &&
366
+ parameter.length > 0
367
+ ? true
368
+ : falseFunction(isNonEmptyArray);
369
+ }
370
+
371
+ /**
372
+ * Check if parameter is a non empty object
373
+ */
374
+ export function isNonEmptyObject(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
375
+ return parameter !== null &&
376
+ typeof parameter !== 'undefined' &&
377
+ parameter.constructor === Object &&
378
+ Object.keys(parameter).length !== 0
379
+ ? true
380
+ : falseFunction(isNonEmptyObject);
381
+ }
382
+
383
+ /**
384
+ * Check if parameter is a non empty string
385
+ */
386
+ export function isNonEmptyString(parameter: string, falseFunction: (...params) => any = errorFunction): boolean {
387
+ return typeof parameter === 'string' && parameter.length > 0 ? true : falseFunction(isNonEmptyString);
388
+ }
389
+
390
+ /**
391
+ * Check if parameter is a number
392
+ */
393
+ export function isNumber(parameter: number, falseFunction: (...params) => any = errorFunction): boolean {
394
+ return typeof parameter === 'number' ? true : falseFunction(isNumber);
395
+ }
396
+
397
+ /**
398
+ * Check if parameter is an object
399
+ */
400
+ export function isObject(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
401
+ return parameter !== null && typeof parameter !== 'undefined' && parameter.constructor === Object
402
+ ? true
403
+ : falseFunction(isObject);
404
+ }
405
+
406
+ /**
407
+ * Check whether the parameter can be converted to true
408
+ */
409
+ export function isTrue(parameter: any, falseFunction: (...params) => any = errorFunction): boolean {
410
+ return !!parameter ? true : falseFunction(isTrue);
411
+ }
412
+
413
+ /**
414
+ * Check if parameter is a string
415
+ */
416
+ export function isString(parameter: string, falseFunction: (...params) => any = errorFunction): boolean {
417
+ return typeof parameter === 'string' ? true : falseFunction(isString);
418
+ }
419
+
420
+ /**
421
+ * Alternative for errorFunction
422
+ */
423
+ export function returnFalse(): boolean {
424
+ return false;
425
+ }
426
+
427
+ /**
428
+ * Map values into specific type
429
+ */
430
+ export function mapClass<T>(values: Partial<T>, ctor: new () => T, cloneDeep = true): T {
431
+ const instance = new ctor();
432
+
433
+ return Object.keys(instance).reduce((obj, key) => {
434
+ obj[key] = cloneDeep ? _.cloneDeep(values[key]) : values[key];
435
+ return obj;
436
+ }, instance);
437
+ }
438
+
439
+ /**
440
+ * Get type of array (via first item)
441
+ */
442
+ export function typeofArray(arr: any[], strict = false): string {
443
+ let type: string = undefined;
444
+ if (!arr?.length) {
445
+ return type;
446
+ }
447
+ type = typeof arr[0];
448
+ if (strict) {
449
+ for (const item of arr) {
450
+ if (typeof item !== type) {
451
+ return undefined;
452
+ }
453
+ }
454
+ }
455
+ return type;
456
+ }
457
+
458
+ /**
459
+ * Get instance of array items (via first item)
460
+ */
461
+ export function instanceofArray(arr: any[], strict = false): string {
462
+ let constructor: string = undefined;
463
+ if (!arr?.length) {
464
+ return constructor;
465
+ }
466
+ try {
467
+ constructor = arr[0].constructor;
468
+ if (strict) {
469
+ for (const item of arr) {
470
+ if (item.constructor !== constructor) {
471
+ return undefined;
472
+ }
473
+ }
474
+ }
475
+ } catch (e) {
476
+ return undefined;
237
477
  }
478
+ return constructor;
238
479
  }