@lenne.tech/nest-server 11.1.1 → 11.1.3

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 (25) hide show
  1. package/dist/core/common/args/pagination.args.js +5 -4
  2. package/dist/core/common/args/pagination.args.js.map +1 -1
  3. package/dist/core/common/decorators/unified-field.decorator.d.ts +2 -0
  4. package/dist/core/common/decorators/unified-field.decorator.js +8 -6
  5. package/dist/core/common/decorators/unified-field.decorator.js.map +1 -1
  6. package/dist/core/common/helpers/input.helper.js +3 -0
  7. package/dist/core/common/helpers/input.helper.js.map +1 -1
  8. package/dist/core/common/inputs/single-filter.input.js +2 -1
  9. package/dist/core/common/inputs/single-filter.input.js.map +1 -1
  10. package/dist/core/common/models/core-persistence.model.d.ts +2 -2
  11. package/dist/core/common/models/core-persistence.model.js +34 -24
  12. package/dist/core/common/models/core-persistence.model.js.map +1 -1
  13. package/dist/core/modules/health-check/core-health-check-result.model.js +6 -3
  14. package/dist/core/modules/health-check/core-health-check-result.model.js.map +1 -1
  15. package/dist/server/modules/user/user.model.js +0 -2
  16. package/dist/server/modules/user/user.model.js.map +1 -1
  17. package/dist/tsconfig.build.tsbuildinfo +1 -1
  18. package/package.json +1 -1
  19. package/src/core/common/args/pagination.args.ts +5 -4
  20. package/src/core/common/decorators/unified-field.decorator.ts +13 -7
  21. package/src/core/common/helpers/input.helper.ts +5 -0
  22. package/src/core/common/inputs/single-filter.input.ts +2 -1
  23. package/src/core/common/models/core-persistence.model.ts +34 -21
  24. package/src/core/modules/health-check/core-health-check-result.model.ts +6 -3
  25. package/src/server/modules/user/user.model.ts +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lenne.tech/nest-server",
3
- "version": "11.1.1",
3
+ "version": "11.1.3",
4
4
  "description": "Modern, fast, powerful Node.js web framework in TypeScript based on Nest with a GraphQL API and a connection to MongoDB (or other databases).",
5
5
  "keywords": [
6
6
  "node",
@@ -12,8 +12,9 @@ export class PaginationArgs extends CoreInput {
12
12
  */
13
13
  @UnifiedField({
14
14
  description: 'Limit specifies the maximum number of elements found that are to be returned',
15
+ gqlType: Int,
15
16
  isOptional: true,
16
- type: Int,
17
+ type: Number,
17
18
  })
18
19
  limit?: number = undefined;
19
20
 
@@ -22,8 +23,8 @@ export class PaginationArgs extends CoreInput {
22
23
  */
23
24
  @UnifiedField({
24
25
  description: 'Alias for skip',
26
+ gqlType: Int,
25
27
  isOptional: true,
26
- type: Int,
27
28
  })
28
29
  offset?: number = undefined;
29
30
 
@@ -32,8 +33,8 @@ export class PaginationArgs extends CoreInput {
32
33
  */
33
34
  @UnifiedField({
34
35
  description: 'Skip specifies how many found elements should be skipped on return',
36
+ gqlType: Int,
35
37
  isOptional: true,
36
- type: Int,
37
38
  })
38
39
  skip?: number = undefined;
39
40
 
@@ -52,8 +53,8 @@ export class PaginationArgs extends CoreInput {
52
53
  */
53
54
  @UnifiedField({
54
55
  description: 'Alias for limit',
56
+ gqlType: Int,
55
57
  isOptional: true,
56
- type: () => Int,
57
58
  })
58
59
  take?: number = undefined;
59
60
 
@@ -41,6 +41,10 @@ export interface UnifiedFieldOptions {
41
41
  example?: any;
42
42
  /** Options for graphql */
43
43
  gqlOptions?: FieldOptions;
44
+ /** Type if Swagger & Gql types arent compatible */
45
+ gqlType?: GraphQLScalarType | (new (...args: any[]) => any) | Record<number | string, number | string>;
46
+ /** If the property is Any (skips all Validation) */
47
+ isAny?: boolean;
44
48
  /** Default: false */
45
49
  isOptional?: boolean;
46
50
  /** Restricted roles */
@@ -148,8 +152,8 @@ export function UnifiedField(opts: UnifiedFieldOptions = {}): PropertyDecorator
148
152
 
149
153
  // Type function for gql
150
154
  const gqlTypeFn = isArrayField
151
- ? () => [opts.enum?.enum || resolvedTypeFn()]
152
- : () => opts.enum?.enum || resolvedTypeFn();
155
+ ? () => [opts.enum?.enum || opts.gqlType || resolvedTypeFn()]
156
+ : () => opts.enum?.enum || opts.gqlType || resolvedTypeFn();
153
157
 
154
158
  // Gql decorator
155
159
  Field(gqlTypeFn, gqlOpts)(target, propertyKey);
@@ -202,10 +206,10 @@ export function UnifiedField(opts: UnifiedFieldOptions = {}): PropertyDecorator
202
206
  IsNotEmpty()(target, propertyKey);
203
207
  }
204
208
 
205
- // Custom or builtin validator
209
+ // Completely skip validation if its any
206
210
  if (opts.validator) {
207
211
  opts.validator(valOpts).forEach(d => d(target, propertyKey));
208
- } else {
212
+ } else if (!opts.isAny) {
209
213
  const validator = getBuiltInValidator(baseType, valOpts, isArrayField, target);
210
214
  if (validator) {
211
215
  validator(target, propertyKey);
@@ -217,10 +221,12 @@ export function UnifiedField(opts: UnifiedFieldOptions = {}): PropertyDecorator
217
221
  IsEnum(opts.enum.enum, opts.enum.options)(target, propertyKey);
218
222
  }
219
223
 
224
+ if (!opts.isAny) {
220
225
  // Check if it's a primitive, if not apply transform
221
- if (!isPrimitive(baseType) && !opts.enum && !isGraphQLScalar(baseType)) {
222
- Type(() => baseType)(target, propertyKey);
223
- ValidateNested({ each: isArrayField })(target, propertyKey);
226
+ if (!isPrimitive(baseType) && !opts.enum && !isGraphQLScalar(baseType)) {
227
+ Type(() => baseType)(target, propertyKey);
228
+ ValidateNested({ each: isArrayField })(target, propertyKey);
229
+ }
224
230
  }
225
231
 
226
232
  // Roles
@@ -319,6 +319,11 @@ export async function check(
319
319
  * Check if input is a valid Date format and return a new Date
320
320
  */
321
321
  export function checkAndGetDate(input: any): Date {
322
+ // Get timestamp from string
323
+ if (typeof input === 'string' && /^\d+$/.test(input)) {
324
+ input = parseInt(input, 10);
325
+ }
326
+
322
327
  // Create date from value
323
328
  const date = new Date(input);
324
329
 
@@ -78,9 +78,10 @@ export class SingleFilterInput extends CoreInput {
78
78
 
79
79
  @UnifiedField({
80
80
  description: 'Value of the property',
81
+ gqlType: JSON,
82
+ isAny: true,
81
83
  isOptional: true,
82
84
  roles: RoleEnum.S_EVERYONE,
83
- type: () => JSON,
84
85
  })
85
86
  value: any = undefined;
86
87
  }
@@ -36,6 +36,38 @@ export abstract class CorePersistenceModel extends CoreModel {
36
36
  return new Types.ObjectId(this.id);
37
37
  }
38
38
 
39
+ /**
40
+ * Getter for created date as Unix timestamp
41
+ */
42
+ @UnifiedField({
43
+ description: 'Created date (Unix timestamp)',
44
+ isOptional: true,
45
+ roles: RoleEnum.S_EVERYONE,
46
+ swaggerApiOptions: { example: 1740037703939, format: 'int64', type: Number },
47
+ })
48
+ get createdTs(): number {
49
+ if (this.createdAt instanceof Date) {
50
+ return this.createdAt.getTime();
51
+ }
52
+ return this.createdAt;
53
+ }
54
+
55
+ /**
56
+ * Getter for updated date as Unix timestamp
57
+ */
58
+ @UnifiedField({
59
+ description: 'Updated date (Unix timestamp)',
60
+ isOptional: true,
61
+ roles: RoleEnum.S_EVERYONE,
62
+ swaggerApiOptions: { example: 1740037703939, format: 'int64', type: Date },
63
+ })
64
+ get updatedTs(): number {
65
+ if (this.updatedAt instanceof Date) {
66
+ return this.updatedAt.getTime();
67
+ }
68
+ return this.updatedAt;
69
+ }
70
+
39
71
  // ===========================================================================
40
72
  // Properties
41
73
  // ===========================================================================
@@ -53,7 +85,7 @@ export abstract class CorePersistenceModel extends CoreModel {
53
85
  /**
54
86
  * Created date, is set automatically by mongoose
55
87
  */
56
- @Prop({ onCreate: () => new Date() })
88
+ @Prop()
57
89
  @UnifiedField({
58
90
  description: 'Created date',
59
91
  isOptional: true,
@@ -63,18 +95,10 @@ export abstract class CorePersistenceModel extends CoreModel {
63
95
  })
64
96
  createdAt: Date = undefined;
65
97
 
66
- @Prop({ onCreate: () => Date.now() })
67
- @UnifiedField({
68
- description: 'Created date (Unix timestamp)',
69
- roles: RoleEnum.S_EVERYONE,
70
- swaggerApiOptions: { example: 1740037703939, format: 'int64', type: Date },
71
- })
72
- createdTs: number = undefined;
73
-
74
98
  /**
75
99
  * Updated date is set automatically by mongoose
76
100
  */
77
- @Prop({ onUpdate: () => new Date() })
101
+ @Prop()
78
102
  @UnifiedField({
79
103
  description: 'Updated date',
80
104
  isOptional: true,
@@ -84,14 +108,6 @@ export abstract class CorePersistenceModel extends CoreModel {
84
108
  })
85
109
  updatedAt: Date = undefined;
86
110
 
87
- @Prop({ onUpdate: () => Date.now() })
88
- @UnifiedField({
89
- description: 'Updated date (Unix timestamp)',
90
- roles: RoleEnum.S_EVERYONE,
91
- swaggerApiOptions: { example: 1740037703939, format: 'int64', type: Date },
92
- })
93
- updatedTs: number = undefined;
94
-
95
111
  // ===========================================================================
96
112
  // Methods
97
113
  // ===========================================================================
@@ -103,9 +119,6 @@ export abstract class CorePersistenceModel extends CoreModel {
103
119
  super.init();
104
120
  this.createdAt = this.createdAt === undefined ? new Date() : this.createdAt;
105
121
  this.updatedAt = this.updatedAt === undefined ? this.createdAt : this.updatedAt;
106
-
107
- this.createdTs = this.createdTs === undefined ? Date.now() : this.createdTs;
108
- this.updatedTs = this.updatedTs === undefined ? this.createdTs : this.updatedTs;
109
122
  return this;
110
123
  }
111
124
 
@@ -31,9 +31,10 @@ export abstract class CoreHealthCheckResult extends CoreModel {
31
31
  */
32
32
  @UnifiedField({
33
33
  description: 'The info object contains information of each health indicator which is of status “up”',
34
+ gqlType: JSON,
34
35
  isOptional: true,
35
36
  roles: RoleEnum.S_EVERYONE,
36
- type: () => JSON,
37
+ type: () => Object,
37
38
  })
38
39
  info: JSON = undefined;
39
40
 
@@ -42,9 +43,10 @@ export abstract class CoreHealthCheckResult extends CoreModel {
42
43
  */
43
44
  @UnifiedField({
44
45
  description: 'The error object contains information of each health indicator which is of status “down”',
46
+ gqlType: JSON,
45
47
  isOptional: true,
46
48
  roles: RoleEnum.S_EVERYONE,
47
- type: () => JSON,
49
+ type: () => Object,
48
50
  })
49
51
  error: JSON = undefined;
50
52
 
@@ -53,9 +55,10 @@ export abstract class CoreHealthCheckResult extends CoreModel {
53
55
  */
54
56
  @UnifiedField({
55
57
  description: 'The details object contains information of every health indicator',
58
+ gqlType: JSON,
56
59
  isOptional: true,
57
60
  roles: RoleEnum.S_EVERYONE,
58
- type: () => JSON,
61
+ type: () => Object,
59
62
  })
60
63
  details: JSON = undefined;
61
64
  }
@@ -116,8 +116,6 @@ export class User extends CoreUserModel implements PersistenceModel {
116
116
  this.createdBy = null;
117
117
  this.updatedAt = null;
118
118
  this.updatedBy = null;
119
- this.createdTs = null;
120
- this.updatedAt = null;
121
119
  }
122
120
 
123
121
  // Return prepared user