Spaces:
Running
Running
Commit
·
f402448
1
Parent(s):
532c8f0
update(swagger-request): read nested
Browse files- src/common/models/exercise.model.ts +2 -0
- src/common/serializers/exercise.serialization.ts +5 -1
- src/common/serializers/exercisePopulate.serialization.ts +4 -0
- src/lib/decorators/swagger-request.decorator.ts +23 -6
- src/lib/decorators/swagger-response.decorator.ts +9 -4
- src/modules/console/modules/exercises/controllers/exercises.controller.ts +1 -1
- src/modules/console/modules/exercises/validations/create-excercise.validation.ts +5 -1
- src/modules/console/modules/exercises/validations/update-excercise.validation.ts +19 -4
src/common/models/exercise.model.ts
CHANGED
|
@@ -18,6 +18,7 @@ export interface IExercise {
|
|
| 18 |
secondary: ObjectId;
|
| 19 |
}
|
| 20 |
equipments: ObjectId[];
|
|
|
|
| 21 |
media: {
|
| 22 |
type: "image" | "video";
|
| 23 |
url: string;
|
|
@@ -41,6 +42,7 @@ const exerciseSchema = new Schema({
|
|
| 41 |
secondary: { type: Schema.Types.ObjectId, ref: "muscles" },
|
| 42 |
},
|
| 43 |
equipments: [{ type: Schema.Types.ObjectId, ref: "equipments" }],
|
|
|
|
| 44 |
media: {
|
| 45 |
type: {
|
| 46 |
type: String,
|
|
|
|
| 18 |
secondary: ObjectId;
|
| 19 |
}
|
| 20 |
equipments: ObjectId[];
|
| 21 |
+
coverImage: string;
|
| 22 |
media: {
|
| 23 |
type: "image" | "video";
|
| 24 |
url: string;
|
|
|
|
| 42 |
secondary: { type: Schema.Types.ObjectId, ref: "muscles" },
|
| 43 |
},
|
| 44 |
equipments: [{ type: Schema.Types.ObjectId, ref: "equipments" }],
|
| 45 |
+
coverImage: { type: String, required: true },
|
| 46 |
media: {
|
| 47 |
type: {
|
| 48 |
type: String,
|
src/common/serializers/exercise.serialization.ts
CHANGED
|
@@ -77,9 +77,13 @@ export class ExerciseSerialization {
|
|
| 77 |
@Expose()
|
| 78 |
@SwaggerResponseProperty({ type: ["string"] })
|
| 79 |
equipments: any;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
@Expose({ name: "media" })
|
| 82 |
@SwaggerResponseProperty({ type: Media })
|
| 83 |
@Transform(({ value }) => serialize(value, Media))
|
| 84 |
-
media:
|
| 85 |
}
|
|
|
|
| 77 |
@Expose()
|
| 78 |
@SwaggerResponseProperty({ type: ["string"] })
|
| 79 |
equipments: any;
|
| 80 |
+
|
| 81 |
+
@Expose()
|
| 82 |
+
@SwaggerResponseProperty('string')
|
| 83 |
+
coverImage: string;
|
| 84 |
|
| 85 |
@Expose({ name: "media" })
|
| 86 |
@SwaggerResponseProperty({ type: Media })
|
| 87 |
@Transform(({ value }) => serialize(value, Media))
|
| 88 |
+
media: Media;
|
| 89 |
}
|
src/common/serializers/exercisePopulate.serialization.ts
CHANGED
|
@@ -80,6 +80,10 @@ export class ExercisePopulateSerialization {
|
|
| 80 |
@SwaggerResponseProperty({ type: [EquipmentSerialization] })
|
| 81 |
equipments: any;
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
@Expose({ name: "media" })
|
| 84 |
@SwaggerResponseProperty({ type: MediaPopulate })
|
| 85 |
@Transform(({ value }) => serialize(value, MediaPopulate))
|
|
|
|
| 80 |
@SwaggerResponseProperty({ type: [EquipmentSerialization] })
|
| 81 |
equipments: any;
|
| 82 |
|
| 83 |
+
@Expose()
|
| 84 |
+
@SwaggerResponseProperty('string')
|
| 85 |
+
coverImage: string;
|
| 86 |
+
|
| 87 |
@Expose({ name: "media" })
|
| 88 |
@SwaggerResponseProperty({ type: MediaPopulate })
|
| 89 |
@Transform(({ value }) => serialize(value, MediaPopulate))
|
src/lib/decorators/swagger-request.decorator.ts
CHANGED
|
@@ -1,6 +1,28 @@
|
|
| 1 |
import { swaggerRegistry } from "@lib/swagger/swagger";
|
| 2 |
import { getCallingFileName } from "@lib/utils/calling-file.helper";
|
| 3 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
export const SwaggerRequest = (joiSchema: any) => {
|
| 5 |
return (target: any, propertyKey: string) => {
|
| 6 |
const schema: any = {
|
|
@@ -8,12 +30,7 @@ export const SwaggerRequest = (joiSchema: any) => {
|
|
| 8 |
properties: {},
|
| 9 |
};
|
| 10 |
|
| 11 |
-
|
| 12 |
-
properties.forEach((property) => {
|
| 13 |
-
schema.properties[property] = {
|
| 14 |
-
type: joiSchema.describe().keys[property].type,
|
| 15 |
-
};
|
| 16 |
-
});
|
| 17 |
|
| 18 |
target.constructor['targetName'] = target.constructor.name + getCallingFileName();
|
| 19 |
swaggerRegistry.updateRoute(target.constructor['targetName'], {
|
|
|
|
| 1 |
import { swaggerRegistry } from "@lib/swagger/swagger";
|
| 2 |
import { getCallingFileName } from "@lib/utils/calling-file.helper";
|
| 3 |
|
| 4 |
+
const parseToSchema = (schema: any, joiSchema: any) => {
|
| 5 |
+
joiSchema = joiSchema.describe && joiSchema.describe().keys || joiSchema.keys || joiSchema;
|
| 6 |
+
let properties: any;
|
| 7 |
+
try {
|
| 8 |
+
properties = Object.getOwnPropertyNames(joiSchema);
|
| 9 |
+
} catch (error) {
|
| 10 |
+
console.log(joiSchema)
|
| 11 |
+
}
|
| 12 |
+
properties.forEach((property) => {
|
| 13 |
+
const type = joiSchema[property].type;
|
| 14 |
+
if (type === "object") {
|
| 15 |
+
schema.properties[property] = {
|
| 16 |
+
type: "object",
|
| 17 |
+
properties: {},
|
| 18 |
+
};
|
| 19 |
+
parseToSchema(schema.properties[property], joiSchema[property]);
|
| 20 |
+
} else {
|
| 21 |
+
schema.properties[property] = {type};
|
| 22 |
+
}
|
| 23 |
+
});
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
export const SwaggerRequest = (joiSchema: any) => {
|
| 27 |
return (target: any, propertyKey: string) => {
|
| 28 |
const schema: any = {
|
|
|
|
| 30 |
properties: {},
|
| 31 |
};
|
| 32 |
|
| 33 |
+
parseToSchema(schema, joiSchema)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
target.constructor['targetName'] = target.constructor.name + getCallingFileName();
|
| 36 |
swaggerRegistry.updateRoute(target.constructor['targetName'], {
|
src/lib/decorators/swagger-response.decorator.ts
CHANGED
|
@@ -54,10 +54,15 @@ const responseToSwaggerSchema = (response: any) => {
|
|
| 54 |
);
|
| 55 |
schema.properties[property].type = "array";
|
| 56 |
} else {
|
| 57 |
-
schema.properties[property].
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
}
|
| 62 |
}
|
| 63 |
|
|
|
|
| 54 |
);
|
| 55 |
schema.properties[property].type = "array";
|
| 56 |
} else {
|
| 57 |
+
if(Array.isArray(schema.properties[property].type[0])){
|
| 58 |
+
schema.properties[property].enum = schema.properties[property].type[0]
|
| 59 |
+
schema.properties[property].type = "string";
|
| 60 |
+
}else{
|
| 61 |
+
schema.properties[property].items = {
|
| 62 |
+
type: schema.properties[property].type[0],
|
| 63 |
+
};
|
| 64 |
+
schema.properties[property].type = "array";
|
| 65 |
+
}
|
| 66 |
}
|
| 67 |
}
|
| 68 |
|
src/modules/console/modules/exercises/controllers/exercises.controller.ts
CHANGED
|
@@ -63,7 +63,7 @@ export class ExercisesController extends BaseController {
|
|
| 63 |
populateArray: [
|
| 64 |
{ path: "targetMuscles.primary" },
|
| 65 |
{ path: "targetMuscles.secondary" },
|
| 66 |
-
{ path: "
|
| 67 |
],
|
| 68 |
}
|
| 69 |
);
|
|
|
|
| 63 |
populateArray: [
|
| 64 |
{ path: "targetMuscles.primary" },
|
| 65 |
{ path: "targetMuscles.secondary" },
|
| 66 |
+
{ path: "equipments" },
|
| 67 |
],
|
| 68 |
}
|
| 69 |
);
|
src/modules/console/modules/exercises/validations/create-excercise.validation.ts
CHANGED
|
@@ -13,8 +13,12 @@ export interface ICreateExercise {
|
|
| 13 |
sets: number;
|
| 14 |
instructions: string;
|
| 15 |
benefits: string;
|
| 16 |
-
targetMuscles:
|
|
|
|
|
|
|
|
|
|
| 17 |
equipments: string[]; // refs
|
|
|
|
| 18 |
media: {
|
| 19 |
type: "image" | "video";
|
| 20 |
url: string;
|
|
|
|
| 13 |
sets: number;
|
| 14 |
instructions: string;
|
| 15 |
benefits: string;
|
| 16 |
+
targetMuscles: {
|
| 17 |
+
primary: string;
|
| 18 |
+
secondary: string;
|
| 19 |
+
};
|
| 20 |
equipments: string[]; // refs
|
| 21 |
+
coverImage: string,
|
| 22 |
media: {
|
| 23 |
type: "image" | "video";
|
| 24 |
url: string;
|
src/modules/console/modules/exercises/validations/update-excercise.validation.ts
CHANGED
|
@@ -13,8 +13,12 @@ export interface IUpdateExercise {
|
|
| 13 |
sets?: number;
|
| 14 |
instructions?: string;
|
| 15 |
benefits?: string;
|
| 16 |
-
targetMuscles?:
|
|
|
|
|
|
|
|
|
|
| 17 |
equipments?: string[]; // refs
|
|
|
|
| 18 |
media?: {
|
| 19 |
type: "image" | "video";
|
| 20 |
url: string;
|
|
@@ -63,14 +67,25 @@ export const updateExerciseSchema = createSchema<IUpdateExercise>({
|
|
| 63 |
"any.required": "benefits is required",
|
| 64 |
"string.empty": "benefits can not be empty",
|
| 65 |
}),
|
| 66 |
-
targetMuscles: joi.
|
| 67 |
-
|
| 68 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
}),
|
| 70 |
equipments: joi.array().items(joi.string()).empty().optional().messages({
|
| 71 |
"array.base": "please enter a valid equipments",
|
| 72 |
"any.required": "equipments is required",
|
| 73 |
}),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
media: joi.object().keys({
|
| 75 |
type: joi.string().valid("image", "video").optional().messages({
|
| 76 |
"string.base": "please enter a valid media type",
|
|
|
|
| 13 |
sets?: number;
|
| 14 |
instructions?: string;
|
| 15 |
benefits?: string;
|
| 16 |
+
targetMuscles?: {
|
| 17 |
+
primary: string;
|
| 18 |
+
secondary: string;
|
| 19 |
+
};
|
| 20 |
equipments?: string[]; // refs
|
| 21 |
+
coverImage?: string,
|
| 22 |
media?: {
|
| 23 |
type: "image" | "video";
|
| 24 |
url: string;
|
|
|
|
| 67 |
"any.required": "benefits is required",
|
| 68 |
"string.empty": "benefits can not be empty",
|
| 69 |
}),
|
| 70 |
+
targetMuscles: joi.object().keys({
|
| 71 |
+
primary: joi.string().empty().optional().messages({
|
| 72 |
+
"string.base": "please enter a valid primary muscle",
|
| 73 |
+
"any.required": "primary muscle is required",
|
| 74 |
+
}),
|
| 75 |
+
secondary: joi.string().empty().optional().messages({
|
| 76 |
+
"string.base": "please enter a valid secondary muscle",
|
| 77 |
+
"any.required": "secondary muscle is required",
|
| 78 |
+
}),
|
| 79 |
}),
|
| 80 |
equipments: joi.array().items(joi.string()).empty().optional().messages({
|
| 81 |
"array.base": "please enter a valid equipments",
|
| 82 |
"any.required": "equipments is required",
|
| 83 |
}),
|
| 84 |
+
coverImage: joi.string().empty().optional().messages({
|
| 85 |
+
"string.base": "please enter a valid cover image",
|
| 86 |
+
"any.required": "cover image is required",
|
| 87 |
+
"string.empty": "cover image can not be empty",
|
| 88 |
+
}),
|
| 89 |
media: joi.object().keys({
|
| 90 |
type: joi.string().valid("image", "video").optional().messages({
|
| 91 |
"string.base": "please enter a valid media type",
|