moahmedwafy commited on
Commit
2b9d1fb
·
unverified ·
2 Parent(s): 6837dc6 da50ce9

Merge pull request #54 from Modarb-Ai-Trainer:docs

Browse files
src/common/serializers/equipment.serialization.ts CHANGED
@@ -1,12 +1,16 @@
 
1
  import { Expose } from "class-transformer";
2
 
3
  export class MuscleSerialization {
4
- @Expose({ name: "_id" })
5
- id: string;
 
6
 
7
- @Expose()
8
- name: string;
 
9
 
10
- @Expose()
11
- image: string;
 
12
  }
 
1
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
2
  import { Expose } from "class-transformer";
3
 
4
  export class MuscleSerialization {
5
+ @Expose({ name: "_id" })
6
+ @SwaggerResponseProperty({ type: "string" })
7
+ id: string;
8
 
9
+ @Expose()
10
+ @SwaggerResponseProperty({ type: "string" })
11
+ name: string;
12
 
13
+ @Expose()
14
+ @SwaggerResponseProperty({ type: "string" })
15
+ image: string;
16
  }
src/common/serializers/exercise.serialization.ts CHANGED
@@ -1,62 +1,75 @@
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
 
3
 
4
  class ExpectedDurationRange {
5
  @Expose()
 
6
  min: number;
7
 
8
  @Expose()
 
9
  max: number;
10
  }
11
 
12
  class Media {
13
  @Expose()
 
14
  type: string;
15
 
16
  @Expose()
 
17
  url: string;
18
  }
19
 
20
  export class ExerciseSerialization {
21
  @Expose({ name: "_id" })
 
22
  id: string;
23
 
24
  @Expose()
 
25
  name: string;
26
 
27
  @Expose()
 
28
  category: string;
29
 
30
  @Expose()
 
31
  duration: number | null;
32
 
33
  @Expose({ name: "expectedDurationRange" })
34
- @Transform(
35
- ({ value }) => serialize(value, ExpectedDurationRange)
36
- )
37
  expectedDurationRange: object;
38
 
39
  @Expose()
 
40
  reps: number;
41
 
42
  @Expose()
 
43
  sets: number;
44
 
45
  @Expose()
 
46
  instructions: string;
47
 
48
  @Expose()
 
49
  benefits: string;
50
 
51
  @Expose()
 
52
  targetMuscles: any;
53
 
54
  @Expose()
 
55
  equipments: any;
56
 
57
  @Expose({ name: "media" })
58
- @Transform(
59
- ({ value }) => serialize(value, Media)
60
- )
61
  media: object;
62
  }
 
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
3
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
4
 
5
  class ExpectedDurationRange {
6
  @Expose()
7
+ @SwaggerResponseProperty({ type: "number" })
8
  min: number;
9
 
10
  @Expose()
11
+ @SwaggerResponseProperty({ type: "number" })
12
  max: number;
13
  }
14
 
15
  class Media {
16
  @Expose()
17
+ @SwaggerResponseProperty({ type: "string" })
18
  type: string;
19
 
20
  @Expose()
21
+ @SwaggerResponseProperty({ type: "string" })
22
  url: string;
23
  }
24
 
25
  export class ExerciseSerialization {
26
  @Expose({ name: "_id" })
27
+ @SwaggerResponseProperty({ type: "string" })
28
  id: string;
29
 
30
  @Expose()
31
+ @SwaggerResponseProperty({ type: "string" })
32
  name: string;
33
 
34
  @Expose()
35
+ @SwaggerResponseProperty({ type: "string" })
36
  category: string;
37
 
38
  @Expose()
39
+ @SwaggerResponseProperty({ type: "number" })
40
  duration: number | null;
41
 
42
  @Expose({ name: "expectedDurationRange" })
43
+ @SwaggerResponseProperty({ type: {} })
44
+ @Transform(({ value }) => serialize(value, ExpectedDurationRange))
 
45
  expectedDurationRange: object;
46
 
47
  @Expose()
48
+ @SwaggerResponseProperty({ type: "number" })
49
  reps: number;
50
 
51
  @Expose()
52
+ @SwaggerResponseProperty({ type: "number" })
53
  sets: number;
54
 
55
  @Expose()
56
+ @SwaggerResponseProperty({ type: "string" })
57
  instructions: string;
58
 
59
  @Expose()
60
+ @SwaggerResponseProperty({ type: "string" })
61
  benefits: string;
62
 
63
  @Expose()
64
+ @SwaggerResponseProperty({ type: ["string"] })
65
  targetMuscles: any;
66
 
67
  @Expose()
68
+ @SwaggerResponseProperty({ type: ["string"] })
69
  equipments: any;
70
 
71
  @Expose({ name: "media" })
72
+ @SwaggerResponseProperty({ type: {} })
73
+ @Transform(({ value }) => serialize(value, Media))
 
74
  media: object;
75
  }
src/common/serializers/muscle.serialization.ts CHANGED
@@ -1,12 +1,16 @@
 
1
  import { Expose } from "class-transformer";
2
 
3
  export class EquipmentSerialization {
4
  @Expose({ name: "_id" })
 
5
  id: string;
6
 
7
  @Expose()
 
8
  name: string;
9
 
10
  @Expose()
 
11
  image: string;
12
  }
 
1
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
2
  import { Expose } from "class-transformer";
3
 
4
  export class EquipmentSerialization {
5
  @Expose({ name: "_id" })
6
+ @SwaggerResponseProperty({ type: "string" })
7
  id: string;
8
 
9
  @Expose()
10
+ @SwaggerResponseProperty({ type: "string" })
11
  name: string;
12
 
13
  @Expose()
14
+ @SwaggerResponseProperty({ type: "string" })
15
  image: string;
16
  }
src/common/serializers/template.serialization.ts CHANGED
@@ -1,15 +1,20 @@
 
1
  import { Expose } from "class-transformer";
2
 
3
  export class TemplateSerialization {
4
- @Expose({ name: "_id" })
5
- id: string;
 
6
 
7
- @Expose()
8
- name: string;
 
9
 
10
- @Expose()
11
- user: string;
 
12
 
13
- @Expose()
14
- exercises: string[];
 
15
  }
 
1
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
2
  import { Expose } from "class-transformer";
3
 
4
  export class TemplateSerialization {
5
+ @Expose({ name: "_id" })
6
+ @SwaggerResponseProperty({ type: "string" })
7
+ id: string;
8
 
9
+ @Expose()
10
+ @SwaggerResponseProperty({ type: "string" })
11
+ name: string;
12
 
13
+ @Expose()
14
+ @SwaggerResponseProperty({ type: "string" })
15
+ user: string;
16
 
17
+ @Expose()
18
+ @SwaggerResponseProperty({ type: ["string"] })
19
+ exercises: string[];
20
  }
src/common/serializers/user-registered-workout.serialization.ts CHANGED
@@ -1,61 +1,71 @@
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
3
-
4
 
5
  class Days {
6
  @Expose()
 
7
  day_number: number;
8
 
9
  @Expose()
 
10
  total_number_exercises: number;
11
 
12
  @Expose()
 
13
  day_type: string;
14
 
15
  @Expose({ name: "exercises" })
 
16
  exercises: any;
17
 
18
  @Expose()
19
- is_done: Boolean
 
20
  }
21
 
22
  class Weeks {
23
  @Expose()
 
24
  week_number: number;
25
 
26
  @Expose()
 
27
  week_name: string;
28
 
29
  @Expose()
 
30
  week_description: string;
31
 
32
  @Expose({ name: "days" })
33
- @Transform(
34
- ({ value }) => serialize(value, Days)
35
- )
36
  days: any;
37
 
38
  @Expose()
39
- is_done: Boolean
 
40
  }
41
 
42
  export class UserRegisteredWorkoutsSerialization {
43
  @Expose({ name: "_id" })
 
44
  id: string;
45
 
46
  @Expose()
 
47
  user: string;
48
 
49
  @Expose()
 
50
  workout: string;
51
 
52
  @Expose()
 
53
  is_active: Boolean;
54
 
55
  @Expose({ name: "weeks" })
56
- @Transform(
57
- ({ value }) => serialize(value, Weeks)
58
- )
59
  weeks: any;
60
-
61
- }
 
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
3
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
4
 
5
  class Days {
6
  @Expose()
7
+ @SwaggerResponseProperty({ type: "number" })
8
  day_number: number;
9
 
10
  @Expose()
11
+ @SwaggerResponseProperty({ type: "number" })
12
  total_number_exercises: number;
13
 
14
  @Expose()
15
+ @SwaggerResponseProperty({ type: "string" })
16
  day_type: string;
17
 
18
  @Expose({ name: "exercises" })
19
+ @SwaggerResponseProperty({ type: {} })
20
  exercises: any;
21
 
22
  @Expose()
23
+ @SwaggerResponseProperty({ type: "boolean" })
24
+ is_done: Boolean;
25
  }
26
 
27
  class Weeks {
28
  @Expose()
29
+ @SwaggerResponseProperty({ type: "number" })
30
  week_number: number;
31
 
32
  @Expose()
33
+ @SwaggerResponseProperty({ type: "string" })
34
  week_name: string;
35
 
36
  @Expose()
37
+ @SwaggerResponseProperty({ type: "string" })
38
  week_description: string;
39
 
40
  @Expose({ name: "days" })
41
+ @SwaggerResponseProperty({ type: [Days] })
42
+ @Transform(({ value }) => serialize(value, Days))
 
43
  days: any;
44
 
45
  @Expose()
46
+ @SwaggerResponseProperty({ type: "boolean" })
47
+ is_done: Boolean;
48
  }
49
 
50
  export class UserRegisteredWorkoutsSerialization {
51
  @Expose({ name: "_id" })
52
+ @SwaggerResponseProperty({ type: "string" })
53
  id: string;
54
 
55
  @Expose()
56
+ @SwaggerResponseProperty({ type: "string" })
57
  user: string;
58
 
59
  @Expose()
60
+ @SwaggerResponseProperty({ type: "string" })
61
  workout: string;
62
 
63
  @Expose()
64
+ @SwaggerResponseProperty({ type: "boolean" })
65
  is_active: Boolean;
66
 
67
  @Expose({ name: "weeks" })
68
+ @SwaggerResponseProperty({ type: [Weeks] })
69
+ @Transform(({ value }) => serialize(value, Weeks))
 
70
  weeks: any;
71
+ }
 
src/common/serializers/user.serialization.ts CHANGED
@@ -1,68 +1,83 @@
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
 
3
 
4
  class Preferences {
5
  @Expose()
 
6
  fitness_goal: string;
7
 
8
  @Expose()
 
9
  target_weight: number;
10
 
11
  @Expose()
 
12
  workout_frequency: number;
13
 
14
  @Expose()
 
15
  preferred_days: any;
16
 
17
  @Expose()
 
18
  workout_place: string;
19
 
20
  @Expose()
 
21
  preferred_equipment: any;
22
  }
23
 
24
-
25
  export class UserSerialization {
26
  @Expose({ name: "_id" })
 
27
  id: string;
28
 
29
  @Expose()
 
30
  name: string;
31
 
32
  @Expose()
 
33
  email: string;
34
 
35
  @Expose()
 
36
  image: string;
37
 
38
  @Expose()
 
39
  role: string;
40
 
41
  @Expose()
 
42
  gender: string;
43
 
44
  @Expose({ name: "dob" })
 
45
  @Transform(
46
- ({ value }) => new Date().getFullYear() - (new Date(value).getFullYear())
47
  )
48
  age: number;
49
 
50
  @Expose()
 
51
  height: number;
52
 
53
  @Expose()
 
54
  weight: number;
55
 
56
  @Expose()
 
57
  fitness_level: string;
58
 
59
  @Expose({ name: "preferences" })
60
- @Transform(
61
- ({ value }) => serialize(value, Preferences)
62
- )
63
  preferences: object;
64
 
65
  @Expose()
 
66
  injuries: any;
67
-
68
- }
 
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
3
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
4
 
5
  class Preferences {
6
  @Expose()
7
+ @SwaggerResponseProperty({ type: "string" })
8
  fitness_goal: string;
9
 
10
  @Expose()
11
+ @SwaggerResponseProperty({ type: "number" })
12
  target_weight: number;
13
 
14
  @Expose()
15
+ @SwaggerResponseProperty({ type: "number" })
16
  workout_frequency: number;
17
 
18
  @Expose()
19
+ @SwaggerResponseProperty({ type: {} })
20
  preferred_days: any;
21
 
22
  @Expose()
23
+ @SwaggerResponseProperty({ type: "string" })
24
  workout_place: string;
25
 
26
  @Expose()
27
+ @SwaggerResponseProperty({ type: {} })
28
  preferred_equipment: any;
29
  }
30
 
 
31
  export class UserSerialization {
32
  @Expose({ name: "_id" })
33
+ @SwaggerResponseProperty({ type: "string" })
34
  id: string;
35
 
36
  @Expose()
37
+ @SwaggerResponseProperty({ type: "string" })
38
  name: string;
39
 
40
  @Expose()
41
+ @SwaggerResponseProperty({ type: "string" })
42
  email: string;
43
 
44
  @Expose()
45
+ @SwaggerResponseProperty({ type: "string" })
46
  image: string;
47
 
48
  @Expose()
49
+ @SwaggerResponseProperty({ type: "string" })
50
  role: string;
51
 
52
  @Expose()
53
+ @SwaggerResponseProperty({ type: "string" })
54
  gender: string;
55
 
56
  @Expose({ name: "dob" })
57
+ @SwaggerResponseProperty({ type: "number" })
58
  @Transform(
59
+ ({ value }) => new Date().getFullYear() - new Date(value).getFullYear()
60
  )
61
  age: number;
62
 
63
  @Expose()
64
+ @SwaggerResponseProperty({ type: "number" })
65
  height: number;
66
 
67
  @Expose()
68
+ @SwaggerResponseProperty({ type: "number" })
69
  weight: number;
70
 
71
  @Expose()
72
+ @SwaggerResponseProperty({ type: "string" })
73
  fitness_level: string;
74
 
75
  @Expose({ name: "preferences" })
76
+ @SwaggerResponseProperty({ type: Preferences })
77
+ @Transform(({ value }) => serialize(value, Preferences))
 
78
  preferences: object;
79
 
80
  @Expose()
81
+ @SwaggerResponseProperty({ type: {} })
82
  injuries: any;
83
+ }
 
src/common/serializers/workout.serialization.ts CHANGED
@@ -1,33 +1,42 @@
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
 
3
 
4
 
5
 
6
  class Days {
7
  @Expose()
 
8
  day_number: number;
9
 
10
  @Expose()
 
11
  total_number_exercises: number;
12
 
13
  @Expose()
 
14
  day_type: string;
15
 
16
  @Expose({ name: "exercises" })
 
17
  exercises: any;
18
  }
19
 
20
  class TemplateWeeks {
21
  @Expose()
 
22
  week_number: number;
23
 
24
  @Expose()
 
25
  week_name: string;
26
 
27
  @Expose()
 
28
  week_description: string;
29
 
30
  @Expose({ name: "days" })
 
31
  @Transform(
32
  ({ value }) => serialize(value, Days)
33
  )
@@ -36,39 +45,51 @@ class TemplateWeeks {
36
 
37
  export class WorkoutSerialization {
38
  @Expose({ name: "_id" })
 
39
  id: string;
40
 
41
  @Expose()
 
42
  name: string;
43
 
44
  @Expose()
 
45
  description: string;
46
 
47
  @Expose()
 
48
  type: string;
49
 
50
  @Expose()
 
51
  image: string;
52
 
53
  @Expose()
 
54
  created_by: string;
55
 
56
  @Expose()
 
57
  fitness_level: string;
58
 
59
  @Expose()
 
60
  fitness_goal: string;
61
 
62
  @Expose()
 
63
  place: any;
64
 
65
  @Expose()
 
66
  min_per_day: number;
67
 
68
  @Expose()
 
69
  total_number_days: number;
70
 
71
  @Expose({ name: "template_weeks" })
 
72
  @Transform(
73
  ({ value }) => serialize(value, TemplateWeeks)
74
  )
 
1
  import { Expose, Transform } from "class-transformer";
2
  import { serialize } from "@helpers/serialize";
3
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
4
 
5
 
6
 
7
  class Days {
8
  @Expose()
9
+ @SwaggerResponseProperty({ type: "number" })
10
  day_number: number;
11
 
12
  @Expose()
13
+ @SwaggerResponseProperty({ type: "number" })
14
  total_number_exercises: number;
15
 
16
  @Expose()
17
+ @SwaggerResponseProperty({ type: "string" })
18
  day_type: string;
19
 
20
  @Expose({ name: "exercises" })
21
+ @SwaggerResponseProperty({ type: {} })
22
  exercises: any;
23
  }
24
 
25
  class TemplateWeeks {
26
  @Expose()
27
+ @SwaggerResponseProperty({ type: "number" })
28
  week_number: number;
29
 
30
  @Expose()
31
+ @SwaggerResponseProperty({ type: "string" })
32
  week_name: string;
33
 
34
  @Expose()
35
+ @SwaggerResponseProperty({ type: "string" })
36
  week_description: string;
37
 
38
  @Expose({ name: "days" })
39
+ @SwaggerResponseProperty({ type: [Days] })
40
  @Transform(
41
  ({ value }) => serialize(value, Days)
42
  )
 
45
 
46
  export class WorkoutSerialization {
47
  @Expose({ name: "_id" })
48
+ @SwaggerResponseProperty({ type: "string" })
49
  id: string;
50
 
51
  @Expose()
52
+ @SwaggerResponseProperty({ type: "string" })
53
  name: string;
54
 
55
  @Expose()
56
+ @SwaggerResponseProperty({ type: "string" })
57
  description: string;
58
 
59
  @Expose()
60
+ @SwaggerResponseProperty({ type: "string" })
61
  type: string;
62
 
63
  @Expose()
64
+ @SwaggerResponseProperty({ type: "string" })
65
  image: string;
66
 
67
  @Expose()
68
+ @SwaggerResponseProperty({ type: "string" })
69
  created_by: string;
70
 
71
  @Expose()
72
+ @SwaggerResponseProperty({ type: "string" })
73
  fitness_level: string;
74
 
75
  @Expose()
76
+ @SwaggerResponseProperty({ type: "string" })
77
  fitness_goal: string;
78
 
79
  @Expose()
80
+ @SwaggerResponseProperty({ type: "string" })
81
  place: any;
82
 
83
  @Expose()
84
+ @SwaggerResponseProperty({ type: "number" })
85
  min_per_day: number;
86
 
87
  @Expose()
88
+ @SwaggerResponseProperty({ type: "number" })
89
  total_number_days: number;
90
 
91
  @Expose({ name: "template_weeks" })
92
+ @SwaggerResponseProperty({ type: [TemplateWeeks] })
93
  @Transform(
94
  ({ value }) => serialize(value, TemplateWeeks)
95
  )
src/lib/decorators/swagger-response-property.decorator.ts ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { swaggerRegistry } from "@lib/swagger/swagger";
2
+
3
+ export const SwaggerResponseProperty = (
4
+ props?:
5
+ | {
6
+ name?: string;
7
+ type?: any;
8
+ }
9
+ | string
10
+ ) => {
11
+ if (typeof props === "string") {
12
+ return (target: any, propertyKey: string) => {
13
+ swaggerRegistry.updateSchemaProperty({
14
+ schema: target.constructor.name,
15
+ property: propertyKey,
16
+ type: props,
17
+ });
18
+ };
19
+ }
20
+
21
+ return (target: any, propertyKey: string) => {
22
+ swaggerRegistry.updateSchemaProperty({
23
+ schema: target.constructor.name,
24
+ property: propertyKey,
25
+ newName: props?.name,
26
+ type: props?.type,
27
+ });
28
+ };
29
+ };
src/lib/decorators/swagger-response.decorator.ts CHANGED
@@ -1,41 +1,86 @@
1
  import { swaggerRegistry } from "@lib/swagger/swagger";
2
  import { instanceToPlain } from "class-transformer";
3
 
4
- export const SwaggerResponse = (responseClass: any) => {
5
- return (target: any, propertyKey: string) => {
6
- const isArray = Array.isArray(responseClass);
7
- responseClass = isArray ? responseClass[0] : responseClass;
 
8
 
9
- // turn class to swagger schema
10
- const schema: any = {
11
- type: "object",
12
- properties: {},
13
- };
14
 
15
- // get class properties
16
- let properties = [];
17
- let instance;
18
- try {
19
- instance = new responseClass();
20
- properties = Object.getOwnPropertyNames(instanceToPlain(instance));
21
- } catch (e) {
22
- instance = responseClass;
23
- properties = Object.getOwnPropertyNames(instance);
24
- }
25
- properties.forEach((property) => {
 
 
 
 
 
 
 
 
26
  schema.properties[property] = {
27
  type: (instance[property] && typeof instance[property]) || "string",
28
  };
29
- });
30
 
31
- if (isArray) {
32
- schema.type = "array";
33
- schema.items = {
34
- type: "object",
35
- properties: schema.properties,
36
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  }
38
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  const standardResponseSchema: any = {
40
  type: "object",
41
  properties: {
@@ -44,11 +89,20 @@ export const SwaggerResponse = (responseClass: any) => {
44
  type: "string",
45
  },
46
  status: {
47
- type: "string",
48
  },
49
  },
50
  };
51
 
 
 
 
 
 
 
 
 
 
52
  if (isArray) {
53
  standardResponseSchema.properties.meta = {
54
  type: "object",
 
1
  import { swaggerRegistry } from "@lib/swagger/swagger";
2
  import { instanceToPlain } from "class-transformer";
3
 
4
+ const responseToSwaggerSchema = (response: any) => {
5
+ const isClass = typeof response === "function";
6
+ const responseName =
7
+ (isClass && response.prototype.constructor.name) || undefined;
8
+ const responseData = swaggerRegistry.schemasRegistry.get(responseName);
9
 
10
+ // turn class to swagger schema
11
+ const schema: any = {
12
+ type: "object",
13
+ properties: (isClass && responseData?.properties) || {},
14
+ };
15
 
16
+ // get class properties
17
+ let properties = [];
18
+ let instance;
19
+ try {
20
+ instance = new response();
21
+ properties = Object.getOwnPropertyNames(instanceToPlain(instance));
22
+ } catch (e) {
23
+ instance = response;
24
+ properties = Object.getOwnPropertyNames(instance);
25
+ }
26
+
27
+ if (responseData?.propertiesToExclude) {
28
+ properties = properties.filter(
29
+ (property) => !responseData.propertiesToExclude.includes(property)
30
+ );
31
+ }
32
+
33
+ properties.forEach((property) => {
34
+ if (!schema.properties[property] && !responseData?.properties) {
35
  schema.properties[property] = {
36
  type: (instance[property] && typeof instance[property]) || "string",
37
  };
38
+ }
39
 
40
+ if (schema.properties[property] && !schema.properties[property].type) {
41
+ schema.properties[property].type =
42
+ (instance[property] && typeof instance[property]) || "string";
43
+ }
44
+
45
+ if (Array.isArray(schema.properties[property]?.type)) {
46
+ const isTypeObjectOrClass =
47
+ typeof schema.properties[property].type[0] === "function" ||
48
+ typeof schema.properties[property].type[0] === "object";
49
+
50
+ if (isTypeObjectOrClass) {
51
+ schema.properties[property].items = responseToSwaggerSchema(
52
+ schema.properties[property].type[0]
53
+ );
54
+ schema.properties[property].type = "array";
55
+ } else {
56
+ schema.properties[property].items = {
57
+ type: schema.properties[property].type[0],
58
+ };
59
+ schema.properties[property].type = "array";
60
+ }
61
  }
62
 
63
+ if (
64
+ typeof schema.properties[property]?.type === "function" ||
65
+ typeof schema.properties[property]?.type === "object"
66
+ ) {
67
+ schema.properties[property] = responseToSwaggerSchema(
68
+ schema.properties[property].type
69
+ );
70
+ }
71
+ });
72
+
73
+ return schema;
74
+ };
75
+
76
+ export const SwaggerResponse = (responseClass: any) => {
77
+ return (target: any, propertyKey: string) => {
78
+ const isArray = Array.isArray(responseClass);
79
+ responseClass = isArray ? responseClass[0] : responseClass;
80
+ // turn class to swagger schema
81
+ const schema = responseToSwaggerSchema(responseClass);
82
+
83
+ // add standard response schema
84
  const standardResponseSchema: any = {
85
  type: "object",
86
  properties: {
 
89
  type: "string",
90
  },
91
  status: {
92
+ type: "number",
93
  },
94
  },
95
  };
96
 
97
+ // set schema type to array if response is array
98
+ if (isArray) {
99
+ schema.type = "array";
100
+ schema.items = {
101
+ type: "object",
102
+ properties: schema.properties,
103
+ };
104
+ }
105
+ // add meta for array response
106
  if (isArray) {
107
  standardResponseSchema.properties.meta = {
108
  type: "object",
src/lib/swagger/swagger.ts CHANGED
@@ -2,7 +2,7 @@
2
  * Swagger registry class.
3
  */
4
  class SwaggerRegistry {
5
- public static registry = new Map<
6
  any,
7
  {
8
  routes: {
@@ -17,9 +17,43 @@ class SwaggerRegistry {
17
  }
18
  >();
19
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  public initControllerIfNotExists(controller: any, prefix: string = "") {
21
- if (!SwaggerRegistry.registry.has(controller)) {
22
- SwaggerRegistry.registry.set(controller, {
23
  routes: [],
24
  prefix,
25
  });
@@ -28,9 +62,9 @@ class SwaggerRegistry {
28
 
29
  public setControllerPrefix(controller: any, prefix: string) {
30
  this.initControllerIfNotExists(controller);
31
- const data = SwaggerRegistry.registry.get(controller);
32
  data.prefix = prefix;
33
- SwaggerRegistry.registry.set(controller, data);
34
  }
35
 
36
  public updateRoute(
@@ -44,7 +78,7 @@ class SwaggerRegistry {
44
  }
45
  ) {
46
  this.initControllerIfNotExists(controller);
47
- const data = SwaggerRegistry.registry.get(controller);
48
 
49
  // delete undefined keys
50
  Object.keys(params).forEach(
@@ -60,19 +94,19 @@ class SwaggerRegistry {
60
  data.routes.push(params);
61
  }
62
 
63
- SwaggerRegistry.registry.set(controller, data);
64
  }
65
 
66
  public setControllerTags(controller: any, tags: string[]) {
67
  this.initControllerIfNotExists(controller);
68
- const data = SwaggerRegistry.registry.get(controller);
69
  data.tags = tags;
70
- SwaggerRegistry.registry.set(controller, data);
71
  }
72
 
73
  public generateSwaggerDocument() {
74
  const paths: any = {};
75
- SwaggerRegistry.registry.forEach((value) => {
76
  const controllerData = value;
77
 
78
  controllerData.routes.forEach((route) => {
 
2
  * Swagger registry class.
3
  */
4
  class SwaggerRegistry {
5
+ public controllersRegistry = new Map<
6
  any,
7
  {
8
  routes: {
 
17
  }
18
  >();
19
 
20
+ public schemasRegistry = new Map<
21
+ any,
22
+ {
23
+ properties: {
24
+ [key: string]: any;
25
+ };
26
+ propertiesToExclude: string[];
27
+ }
28
+ >();
29
+
30
+ public initSchemaIfNotExists(schema: any) {
31
+ if (!this.schemasRegistry.has(schema)) {
32
+ this.schemasRegistry.set(schema, {
33
+ properties: {},
34
+ propertiesToExclude: [],
35
+ });
36
+ }
37
+ }
38
+
39
+ public updateSchemaProperty(props: {
40
+ schema: any;
41
+ property: string;
42
+ newName?: string;
43
+ type: any;
44
+ }) {
45
+ this.initSchemaIfNotExists(props.schema);
46
+ const data = this.schemasRegistry.get(props.schema);
47
+ data.properties[props.newName || props.property] = { type: props.type };
48
+ if (props.newName) {
49
+ data.propertiesToExclude.push(props.property);
50
+ }
51
+ this.schemasRegistry.set(props.schema, data);
52
+ }
53
+
54
  public initControllerIfNotExists(controller: any, prefix: string = "") {
55
+ if (!this.controllersRegistry.has(controller)) {
56
+ this.controllersRegistry.set(controller, {
57
  routes: [],
58
  prefix,
59
  });
 
62
 
63
  public setControllerPrefix(controller: any, prefix: string) {
64
  this.initControllerIfNotExists(controller);
65
+ const data = this.controllersRegistry.get(controller);
66
  data.prefix = prefix;
67
+ this.controllersRegistry.set(controller, data);
68
  }
69
 
70
  public updateRoute(
 
78
  }
79
  ) {
80
  this.initControllerIfNotExists(controller);
81
+ const data = this.controllersRegistry.get(controller);
82
 
83
  // delete undefined keys
84
  Object.keys(params).forEach(
 
94
  data.routes.push(params);
95
  }
96
 
97
+ this.controllersRegistry.set(controller, data);
98
  }
99
 
100
  public setControllerTags(controller: any, tags: string[]) {
101
  this.initControllerIfNotExists(controller);
102
+ const data = this.controllersRegistry.get(controller);
103
  data.tags = tags;
104
+ this.controllersRegistry.set(controller, data);
105
  }
106
 
107
  public generateSwaggerDocument() {
108
  const paths: any = {};
109
+ this.controllersRegistry.forEach((value) => {
110
  const controllerData = value;
111
 
112
  controllerData.routes.forEach((route) => {
src/modules/console/common/serializers/admin.serialization.ts CHANGED
@@ -1,27 +1,37 @@
 
1
  import { Expose, Transform } from "class-transformer";
2
 
3
  export class AdminSerialization {
4
  @Expose({ name: "_id" })
 
5
  id: string;
6
 
7
  @Expose()
 
8
  name: string;
9
 
10
  @Expose()
 
11
  email: string;
12
 
13
  @Expose()
 
 
 
14
  image: object;
15
 
16
  @Expose()
 
17
  role: string;
18
 
19
  @Expose()
 
20
  gender: string;
21
 
22
  @Expose({ name: "dob" })
 
23
  @Transform(
24
  ({ value }) => new Date().getFullYear() - new Date(value).getFullYear()
25
  )
26
  age: number;
27
- }
 
1
+ import { SwaggerResponseProperty } from "@lib/decorators/swagger-response-property.decorator";
2
  import { Expose, Transform } from "class-transformer";
3
 
4
  export class AdminSerialization {
5
  @Expose({ name: "_id" })
6
+ @SwaggerResponseProperty("string")
7
  id: string;
8
 
9
  @Expose()
10
+ @SwaggerResponseProperty("string")
11
  name: string;
12
 
13
  @Expose()
14
+ @SwaggerResponseProperty("string")
15
  email: string;
16
 
17
  @Expose()
18
+ @SwaggerResponseProperty({
19
+ type: {},
20
+ })
21
  image: object;
22
 
23
  @Expose()
24
+ @SwaggerResponseProperty("string")
25
  role: string;
26
 
27
  @Expose()
28
+ @SwaggerResponseProperty("string")
29
  gender: string;
30
 
31
  @Expose({ name: "dob" })
32
+ @SwaggerResponseProperty("number")
33
  @Transform(
34
  ({ value }) => new Date().getFullYear() - new Date(value).getFullYear()
35
  )
36
  age: number;
37
+ }