So I am trying to generate a basic documentation for my routing now the routes are not your normal expressjs routes like router.get etc.
My issue is the swagger autogen is not seeing any routes and not making anything on it.
Here is a sample for them
const express = require('express')
const fs = require('fs')
const path = require('path')
const isAuthenticated = require('../../middlewares/authMiddleware')
const isAdmin = require('../../middlewares/isAdmin')
const { hasPermission } = require('../../controllers/permissions')
const router = express.Router()
/**
* The function recursively loads routes from a directory and adds them to a router object.
* @param directory - The directory path where the routes are located.
* @param [currentPath] - The current path is a string representing the current directory path being
* traversed by the function. It is used to construct the endpoint URL for each route based on the
* directory structure. If not provided, it defaults to an empty string.
*/
function loadRoutes(directory, currentPath = '') {
fs.readdirSync(directory, { withFileTypes: true }).forEach((dirent) => {
const fullPath = path.join(directory, dirent.name)
if (dirent.isDirectory()) {
loadRoutes(fullPath, path.join(currentPath, dirent.name))
} else if (dirent.isFile() && !(currentPath === '' && dirent.name === 'index.js')) {
const route = require(fullPath)
console.log(`Loading route: ${route.metadata.method} ${path.join(currentPath, path.parse(dirent.name).name)}`)
const endpoint = route.metadata.url || path.join(currentPath, path.parse(dirent.name).name)
const middlewares = route.metadata?.middlewares || []
if (route.metadata.requiresAuth) {
if (router[route.metadata.method.toLowerCase()]) {
router[route.metadata.method.toLowerCase()](endpoint, isAuthenticated, ...middlewares, route.handler)
}
} else if (route.metadata.requiresPermission && route.metadata.requiresAuth) {
if (hasPermission(route.metadata.permissions)) {
if (router[route.metadata.method.toLowerCase()]) {
router[route.metadata.method.toLowerCase()](endpoint, isAuthenticated, isAdmin, ...middlewares, route.handler)
}
}
} else {
if (router[route.metadata.method.toLowerCase()]) {
router[route.metadata.method.toLowerCase()](endpoint, ...middlewares, route.handler)
}
}
}
})
}
loadRoutes(__dirname)
module.exports = router
This is my handler which loads in the routes that are in multiple sub-sub folders for organizing the routes and here is a sample route
const { PERMISSIONS_MAP } = require('../../../controllers/permissions')
const responseHandler = require('../../../modules/responseHandler')
const database = require('../../../config/database')
const {
Products,
} = database.models
module.exports = {
metadata: {
method: 'GET',
url: '/products/get',
version: '1.0.0',
requiresAuth: false,
permissions: [],
requiresPermission: false,
middlewares: []
},
handler: async (req, res, next) => {
responseHandler(req, res, 200, { products: [] }, null, 'Products retrieved successfully')
}
}
And here is my swagger gen script Yes it is copied from the documentation
const swaggerAutogen = require('swagger-autogen')()
const doc = {
info: {
version: "1.0.0",
title: "My API",
description: "Documentation automatically generated by the <b>swagger-autogen</b> module."
},
host: "localhost:3000",
basePath: "/",
schemes: ['http', 'https'],
consumes: ['application/json'],
produces: ['application/json'],
tags: [
{
"name": "User",
"description": "Endpoints"
}
],
securityDefinitions: {
apiKeyAuth: {
type: "apiKey",
in: "header", // can be "header", "query" or "cookie"
name: "X-API-KEY", // name of the header, query parameter or cookie
description: "any description..."
}
},
definitions: {
Parents: {
father: "Simon Doe",
mother: "Marie Doe"
},
User: {
name: "Jhon Doe",
age: 29,
parents: {
$ref: '#/definitions/Parents'
},
diplomas: [
{
school: "XYZ University",
year: 2020,
completed: true,
internship: {
hours: 290,
location: "XYZ Company"
}
}
]
},
AddUser: {
$name: "Jhon Doe",
$age: 29,
about: ""
}
}
}
const outputFile = './swagger-output.json'
const endpointsFiles = ['./src/routes/v1/index.js']
swaggerAutogen(outputFile, endpointsFiles, doc).then(() => {
require('./app.js') // Your project's root file
})