swagger ui

This commit is contained in:
2026-01-13 02:47:50 +03:00
parent ef452e27fd
commit 785cfc71f5
10 changed files with 329 additions and 4 deletions
+1 -2
View File
@@ -6,7 +6,6 @@
"main": "index.js",
"scripts": {
"start": "node dist/server.js",
"dev": "ts-node --transpile-only src/server.ts",
"build": "tsc",
"lint": "eslint . --ext .ts",
"lint:fix": "eslint . --ext .ts --fix",
@@ -51,4 +50,4 @@
"typescript": "^5.9.3",
"typescript-eslint": "^8.52.0"
}
}
}
+14
View File
@@ -13,6 +13,20 @@ const options = {
url: `http://localhost:${process.env.PORT || 3000}`,
},
],
components: {
securitySchemes: {
BearerAuth: {
type: "http",
scheme: "bearer",
bearerFormat: "JWT",
},
},
},
security: [
{
BearerAuth: [],
},
],
},
apis: ["./src/routes/*.ts", "./src/controllers/*.ts", "./src/models/*.ts"],
};
+40
View File
@@ -75,4 +75,44 @@ const orderSchema = new Schema<OrderDocument>(
},
);
/**
* @openapi
* components:
* schemas:
* Order:
* type: object
* properties:
* _id:
* type: string
* description: The order ID
* userId:
* type: string
* description: The user ID who placed the order
* items:
* type: array
* items:
* type: object
* properties:
* productId:
* type: string
* quantity:
* type: number
* unitPrice:
* type: number
* total:
* type: number
* description: The total order amount in cents
* status:
* type: string
* enum: [created, paid, cancelled]
* description: The order status
* createdAt:
* type: string
* format: date-time
* description: The date the order was created
* updatedAt:
* type: string
* format: date-time
* description: The date the order was updated
*/
export const OrderModel = model<OrderDocument>("Order", orderSchema);
+28
View File
@@ -37,4 +37,32 @@ const productSchema = new Schema<ProductDocument>(
},
);
/**
* @openapi
* components:
* schemas:
* Product:
* type: object
* properties:
* _id:
* type: string
* description: The product ID
* name:
* type: string
* description: The product name
* price:
* type: number
* description: The product price in cents
* stock:
* type: number
* description: The product stock quantity
* createdAt:
* type: string
* format: date-time
* description: The date the product was created
* updatedAt:
* type: string
* format: date-time
* description: The date the product was updated
*/
export const ProductModel = model<ProductDocument>("Product", productSchema);
+26
View File
@@ -40,4 +40,30 @@ const userSchema = new Schema<UserDocument>(
},
);
/**
* @openapi
* components:
* schemas:
* User:
* type: object
* properties:
* _id:
* type: string
* description: The user ID
* email:
* type: string
* description: The user's email
* role:
* type: string
* enum: [admin, customer]
* description: The user's role
* createdAt:
* type: string
* format: date-time
* description: The date the user was created
* updatedAt:
* type: string
* format: date-time
* description: The date the user was updated
*/
export const UserModel = model<UserDocument>("User", userSchema);
+55
View File
@@ -6,6 +6,30 @@ import { registerSchema, loginSchema } from "../validation/auth.schema.js";
const router: Router = Router();
/**
* @openapi
* /auth/register:
* post:
* tags:
* - Auth
* summary: Register a new user
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* password:
* type: string
* responses:
* 201:
* description: User created
* 400:
* description: Invalid input
*/
router.post(
"/register",
authRateLimiter,
@@ -13,6 +37,37 @@ router.post(
AuthController.register,
);
/**
* @openapi
* /auth/login:
* post:
* tags:
* - Auth
* summary: Login a user
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* email:
* type: string
* password:
* type: string
* responses:
* 200:
* description: Login successful
* content:
* application/json:
* schema:
* type: object
* properties:
* token:
* type: string
* 401:
* description: Invalid credentials
*/
router.post(
"/login",
authRateLimiter,
+6 -1
View File
@@ -1,10 +1,15 @@
import express from "express";
import swaggerUi from "swagger-ui-express";
import * as swaggerUi from "swagger-ui-express";
import swaggerSpec from "../config/swagger.js";
import { Router } from "express";
const router: Router = express.Router();
router.use("/", (req, res, next) => {
console.log("Serving Swagger UI at", req.originalUrl);
next();
});
router.use("/", swaggerUi.serve, swaggerUi.setup(swaggerSpec));
export default router;
+92
View File
@@ -10,6 +10,37 @@ import {
const router: Router = Router();
/**
* @openapi
* /orders:
* post:
* tags:
* - Orders
* summary: Create a new order
* security:
* - BearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* properties:
* items:
* type: array
* items:
* type: object
* properties:
* productId:
* type: string
* quantity:
* type: number
* responses:
* 201:
* description: Order created
* 400:
* description: Invalid input
*/
router.post(
"/",
authMiddleware,
@@ -18,8 +49,48 @@ router.post(
OrderController.create,
);
/**
* @openapi
* /orders:
* get:
* tags:
* - Orders
* summary: List my orders
* security:
* - BearerAuth: []
* responses:
* 200:
* description: List of orders
* content:
* application/json:
* schema:
* type: array
* items:
* $ref: '#/components/schemas/Order'
*/
router.get("/", authMiddleware, OrderController.list);
/**
* @openapi
* /orders/{id}/pay:
* post:
* tags:
* - Orders
* summary: Pay for an order
* security:
* - BearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Order paid
* 404:
* description: Order not found
*/
router.post(
"/:id/pay",
authMiddleware,
@@ -27,6 +98,27 @@ router.post(
OrderController.pay,
);
/**
* @openapi
* /orders/{id}/cancel:
* post:
* tags:
* - Orders
* summary: Cancel an order
* security:
* - BearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* responses:
* 200:
* description: Order cancelled
* 404:
* description: Order not found
*/
router.post(
"/:id/cancel",
authMiddleware,
+65
View File
@@ -10,6 +10,27 @@ import {
const router: Router = Router();
/**
* @openapi
* /products:
* post:
* tags:
* - Products
* summary: Create a product
* security:
* - BearerAuth: []
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Product'
* responses:
* 201:
* description: Product created
* 403:
* description: Not authorized
*/
router.post(
"/",
authMiddleware,
@@ -18,6 +39,33 @@ router.post(
ProductController.create,
);
/**
* @openapi
* /products/{id}:
* patch:
* tags:
* - Products
* summary: Update a product
* security:
* - BearerAuth: []
* parameters:
* - in: path
* name: id
* required: true
* schema:
* type: string
* requestBody:
* required: true
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/Product'
* responses:
* 200:
* description: Product updated
* 404:
* description: Product not found
*/
router.patch(
"/:id",
authMiddleware,
@@ -26,6 +74,23 @@ router.patch(
ProductController.update,
);
/**
* @openapi
* /products:
* get:
* tags:
* - Products
* summary: List all products
* responses:
* 200:
* description: List of products
* content:
* application/json:
* schema:
* type: array
* items:
* $ref: '#/components/schemas/Product'
*/
router.get("/", ProductController.list);
export default router;
+2 -1
View File
@@ -39,7 +39,8 @@
"isolatedModules": true,
"noUncheckedSideEffectImports": true,
"moduleDetection": "force",
"skipLibCheck": true
"skipLibCheck": true,
"esModuleInterop": true
},
"include": ["src/**/*"],