knuckleswtf / scribe-js

Generate API documentation for humans from your Node.js codebase.
https://scribe.knuckles.wtf/nodejs/
52 stars 8 forks source link

Generate api docs from different route files #5

Closed chintankotadia closed 3 years ago

chintankotadia commented 3 years ago

Does scribe library supports routes which are imported from different files in expressjs 4.x? I have divided routes into different files and sub files under it for better management like this:

// front routes
require('./app/routes/front')(app);

Code of app/routes/front/index.js

module.exports = function(app) {
  var routeFiles = fs.readdirSync(path.join(__dirname, 'router/'))

  routeFiles.forEach(function(file) {

    if (file === 'index.js' || file.substr(file.lastIndexOf('.') + 1) !== 'js') {
      return;
    }

    var name = file.substr(0, file.indexOf('.'));

    app.use('/', require('./router/' + name));
  });
}
// admin routes
require('./app/routes/admin')(app);

I'm unable to generate api docs. It always gives me undefined handlers on @knuckleswtf\scribe-express\src\get_routes.js [Line no. 55]

Any idea what am I missing over here?

Thank you

shalvah commented 3 years ago

Hmm, it should work. Lemme take a look at that. can you share the error message here?

chintankotadia commented 3 years ago

@shalvah : Thank you for the response. Here are the error details:

TypeError: Cannot read property 'handlers' of undefined
    at mapRouteToEndpointObject (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:53:44)
    at Array.map (<anonymous>)
    at getRoutesFromRouter (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:45:36)
    at mapRouteToEndpointObject (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:59:20)
    at Array.map (<anonymous>)
    at getRoutesFromRouter (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:45:36)
    at module.exports (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:96:12)
    at Command.<anonymous> (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/src/cli.js:92:53)
    at Command.listener [as _actionHandler] (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/node_modules/commander/index.js:413:31)
    at Command._parseCommand (/var/www/zee/restful-api/node_modules/@knuckleswtf/scribe-express/node_modules/commander/index.js:914:14)

Thank you!

shalvah commented 3 years ago

Hey, did you remember to call require('@knuckleswtf/scribe-express')(app) on your Express app before registering routes?

chintankotadia commented 3 years ago

@shalvah : Yes, I did that one in server.js

shalvah commented 3 years ago

What command did you run to generate the docs? npx scribe generate -a server.js?

shalvah commented 3 years ago

I'm going to see some more code from your server.js.

shalvah commented 3 years ago

Re: those routers in your front directory: are you using sub-apps? As in, does each route file create its own express() instance?

chintankotadia commented 3 years ago

Hi @shalvah

Sorry for the late response. Here is the code of the different files :

Code of server.js

const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
var dotenv = require('dotenv');
const App = express();

dotenv.config();

// Set CORS
App.use(cors({ origin: process.env.CORS_ORIGIN }));

App.use(express.json());

// parse requests of content-type - application/x-www-form-urlencoded
App.use(bodyParser.urlencoded({ extended: true }));

// parse requests of content-type - application/json
App.use(bodyParser.json());

// Database
const db = require('./app/models');
db.sequelize.sync();

require('@knuckleswtf/scribe-express')(App)

// route
App.get('/', (req, res) => {
  res.json({
    'message': 'No route matches [GET] /'
  });
});

// open routes
require('./app/routes/open')(App);

// office routes
require('./app/routes/office')(App);

// set port, listen for requests
const PORT = process.env.PORT || 3001;

App.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}.`);
});

module.exports = App;

Code of ./app/routes/open/index.js

var path = require('path')
var fs = require('fs');

/**
 * Middlewares
 */
const { VerifyApiToken } = require('../../middleware');

module.exports = function(App) {
  var routeFiles = fs.readdirSync(path.join(__dirname, 'router/'))

  App.use(VerifyApiToken);

  routeFiles.forEach(function(file) {

    if (file === 'index.js' || file.substr(file.lastIndexOf('.') + 1) !== 'js')
      return;

    var name = file.substr(0, file.indexOf('.'));

    App.use('/', require('./router/' + name));

  });
}

Code of ./app/routes/open/config.js

const authRoute = {
  AUTH_LOGIN: '/auth/login',
  AUTH_REGISTER:'/auth/register',
}

const apiRoute = {
  USER_PROFILE_CREATE: '/user/profile/create',
  USER_PROFILE_SAVE: '/user/profile/save',
}

module.exports = {
  authRoute,
  apiRoute
}

Code of ./app/routes/open/router/profile.js

var express = require('express');
var router = express.Router();

/**
 * Route Configs
 */
const routeConfig = require('../config');
const apiRoute = routeConfig.apiRoute;

/**
 * Validators
 */
const ProfileValidation = require('../../../validators/open/ProfileValidation');

/**
 * Profile Controller
 */
var ProfileController = require('../../../controllers/api/v1/open/ProfileController');
ProfileController = new ProfileController();

/**
 * Profile Routes
 */
router.get(apiRoute.USER_PROFILE_CREATE, ProfileController.create);

router.post(apiRoute.USER_PROFILE_SAVE, [ProfileValidation.validate], ProfileController.save);

module.exports = router;

Please let me know if you need any other information.

Thank you

chintankotadia commented 3 years ago

What command did you run to generate the docs? npx scribe generate -a server.js?

Yes, please.

Re: those routers in your front directory: are you using sub-apps? As in, does each route file create its own express() instance?

Sorry, didn't understand your question but I think my above code might explain your query.

tquangdo commented 3 years ago

I'm also having the same error with chintankotadia, this is my src code:

  1. folder structure image

  2. index.js

    const routes = require('./routes/')
    ...
    const app = express()
    require('@knuckleswtf/scribe-express')(app)
    const router = express.Router()
    ...
    routes(router)
    ...
    app.use('/api', router)
    ...
    module.exports = app
  3. routes/index.js

    const user = require('./user')
    const article = require('./article')
    module.exports = router => {
    user(router)
    article(router)
    }
  4. routes/article.js & user.js

    // declare, define some APIs: GET/POST/DELETE...
  5. errors

    server% npx scribe generate -a index.js
    Express server started at port: 5000
    TypeError: Cannot read property 'handlers' of undefined
    at mapRouteToEndpointObject (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:53:44)
    at Array.map (<anonymous>)
    at getRoutesFromRouter (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:45:36)
    at mapRouteToEndpointObject (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:59:20)
    at Array.map (<anonymous>)
    at getRoutesFromRouter (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:45:36)
    at module.exports (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/get_routes.js:96:12)
    at Command.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/cli.js:92:53)
    at Command.listener [as _actionHandler] (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:413:31)
    at Command._parseCommand (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:914:14)
    at Command._dispatchSubcommand (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:865:18)
    at Command._parseCommand (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:882:12)
    at Command.parse (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:717:10)
    at Object.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/cli.js:108:9)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
tquangdo commented 3 years ago

does each route file create its own express() instance?

No, just only index.js create it. Other route files: routes/index.js & article.js & user.js don't have this code:

const app = express()
shalvah commented 3 years ago

Thanks. I'll take a look at this.

shalvah commented 3 years ago

Thanks guys, been able to reproduce. Coming up with a fix soon.

tquangdo commented 3 years ago

Thanks guys, been able to reproduce. Coming up with a fix soon.

@shalvah I'm sorry but when will we receive the fix version? I'm still waiting for it ^^

shalvah commented 3 years ago

Sorry about that. Turned out to be more involved than I anticipated, plus a lot of personal stuff came up. I'm aiming for something soon, though. Ideally this week.

shalvah commented 3 years ago

Good news: I've now got it working. Will release this week.

shalvah commented 3 years ago

Ah, fuck it. I've tagged v1.3.0, where this should be fixed. Please let me know if it doesn't work.

tquangdo commented 3 years ago

Ah, fuck it. I've tagged v1.3.0, where this should be fixed. Please let me know if it doesn't work.

It seems that it doesn't work, the error "Cannot read property 'handlers' of undefined" is still the same . I uninstalled & reinstalled again by these commands, and the version is still "@knuckleswtf/scribe-express": "^1.2.0"

npm uninstall @knuckleswtf/scribe-express
npm i @knuckleswtf/scribe-express

-> please let me know if i miss any reinstall steps, thanks.

shalvah commented 3 years ago

Hmm, something wrong. The new version doesn't even use a handlers key, so you can't be getting that error if you upgraded.

Try using npm list @knuckleswtf/scribe-express to see the version that's actually installed.

Oh, also, in the new version you don't need to pass your app object. Just add requiree("@knuckleswtf/scribe-express")() to the top of your file (before requiring Express).

tquangdo commented 3 years ago
  1. Try using npm list @knuckleswtf/scribe-express to see the version that's actually installed

→This is the result:

(06/16/21)NC00011462@dotq ~/Documents/GitHub/mern-medium-clone/server(master)# npm list @knuckleswtf/scribe-express
server@1.0.0 /Users/NC00011462/Documents/GitHub/mern-medium-clone/server
└── @knuckleswtf/scribe-express@1.2.0

Besides, I checked in this link, the version is still 1.2.0 in Published 6 months ago https://www.npmjs.com/package/@knuckleswtf/scribe-express -> Did you already up 1.3.0 on npm or not yet?

2. I ran again and there is another error MSG as this:

(06/16/21)NC00011462@dotq ~/Documents/GitHub/mern-medium-clone/server(master)# npx scribe generate -a index.js     
TypeError: Cannot set property '_decoratedByScribe' of undefined
    at module.exports (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/decorator.js:5:28)
    at Object.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/index.js:1:39)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Command.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/cli.js:75:27)
    at Command.listener [as _actionHandler] (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:413:31)

3. This is my github repo, please have a look if you want, thanks ^^ https://github.com/tquangdo/mern-medium-clone

shalvah commented 3 years ago

Weird. Here's 1.3.0, published yesterday. https://www.npmjs.com/package/@knuckleswtf/scribe-express/v/1.3.0

For some reason, 1.2.0 is marked as latest. I'll investigate that. Update your package.json to ^1.3.0.

tquangdo commented 3 years ago

Weird. Here's 1.3.0, published yesterday. https://www.npmjs.com/package/@knuckleswtf/scribe-express/v/1.3.0 For some reason, 1.2.0 is marked as latest. I'll investigate that. Update your package.json to ^1.3.0.

-> I already updated to ^1.3.0 https://github.com/tquangdo/mern-medium-clone/blob/master/server/package.json#L12

but there is another error MSG as this:

(06/16/21)NC00011462@dotq ~/Documents/GitHub/mern-medium-clone/server(master)# npm list @knuckleswtf/scribe-express
server@1.0.0 /Users/NC00011462/Documents/GitHub/mern-medium-clone/server
└── @knuckleswtf/scribe-express@1.3.0

(06/16/21)NC00011462@dotq ~/Documents/GitHub/mern-medium-clone/server(master)# npx scribe generate -a index.js     
TypeError: Cannot read property 'forEach' of undefined
    at Function.use (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/decorator.js:106:16)
    at Object.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/index.js:50:5)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Command.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/cli.js:75:27)
    at Command.listener [as _actionHandler] (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:413:31)
    at Command._parseCommand (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:914:14)
    at Command._dispatchSubcommand (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:865:18)
    at Command._parseCommand (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:882:12)
    at Command.parse (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/commander/index.js:717:10)
    at Object.<anonymous> (/Users/NC00011462/Documents/GitHub/mern-medium-clone/server/node_modules/@knuckleswtf/scribe-express/src/cli.js:109:9)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
shalvah commented 3 years ago

Okay, I'll check that out.

shalvah commented 3 years ago

It's fixed now (1.4.0). Also, npm install should install the correct version now. Was a bug in npm that's been fixed.

shalvah commented 3 years ago

Hey @tquangdo @chintankotadia it works now, yeah?

Also, good news: in the latest version (1.6.0), you no longer need to add the require(...) statement in your code at all. You also don't need to pass a "server file". So npx scribe generate --app index.js should work.

tquangdo commented 3 years ago

image It works, thank you very much! Your support is really nice and quick, good job bro!

Sorry but i haven't understood yet about this sentence. Did you mean that because no need to add require(...) in server/index.jsso that means no need to pass a "server file"?

You also don't need to pass a "server file"

shalvah commented 3 years ago

Oh, it's two separate changes: you don't need to add the require statement and you don't need to pass the server file argument (-s server.js). Once you install, you can just run npx scribe generate --app index.js and it'll work.

shalvah commented 3 years ago

It works

Glad to hear. It's pretty basic right now, but for v2, we're trying to see how we can make Scribe automatically figure out more details about your endpoints.