typescript express get does not work in separate files - node.js

I'm currently converting my node code to node-ts to help our development flow for someone that is going to help out.
I tried using this information (typescript node.js express routes separated files best practices) initially but that didn't work, so as of right now I have this below
In my index.ts I have this on the bottom
import Auth from "./routes/Auth";
app.use('/auth', Auth.Routing());
export = app;
Then in my ./routes/Auth.ts I have this
const Routing = function() {
app.get('/session', User.session);
return app;
}
export = { Routing };
When I try to access /auth/session all it returns is index_1.default.get.
Using the link above, I attempted to use const router = express.Router(); and then export = router and what not but was unable to get it to work for that either with the same error.

Related

Nodjs swagger auto gen integration

I need to develop an API using NodeJS and also need to develop documentation for API also. I integrated with swagger auto-gen for swagger.json creation. But the swagger.json not generating properly if I used routes.js as below
var express = require('express');
module.exports = function(app) {
var userController = require('../controller/userController');
var apiRouter = express.Router();
var routerV1 = express.Router();
var routerV2 = express.Router();
app.use('/admin', apiRouter);
apiRouter.use("/v1", routerV1);
apiRouter.use("/v2", routerV2);
routerV1.route('/users').get(userController.getUsersV1);
routerV2.route('/users').get(userController.getUsersV2);
}
and also mapped these routes.js in swagger.js
Please suggest the best way to generate swagger.js
Do we need to create routes file for all controller?
Version 2 of swagger-autogen added this feature. Previous versions don't recognize routes. In your case, the best way to generate the file swagger.js is:
file: swagger.js
const swaggerAutogen = require('swagger-autogen')();
const outputFile = './swagger_output.json';
const endpointsFiles = ['./routes.js']; // root file where the route starts.
swaggerAutogen(outputFile, endpointsFiles).then(() => {
require('./index.js'); // Your project's root file
})
Update your module to the latest version.
And run your project with: node swagger.js
And about the routes file for all controller, you don't need to implement it for each one, but it also depends on the structure of your code. If you have a root route file like the example, this is enough for all sub-routes to be scanned. I hope it helps you. Take a look at this example if you need to:
swagger-autogen using router

Set "basedir" option for Pug in NestJS

I'm trying to use pug layouts in NestJS, however when extending a layout from an absolute path, pug requires the basedir option to be set.
In ExpressJS you would use app.locals.basedir = ..., what would be the equivalent in NestJS?
const server = await NestFactory.create<NestExpressApplication>(AppModule);
server.setViewEngine('pug');
server.setBaseViewsDir(join(__dirname, 'templates', 'views'));
await server.listen(config.server.port);
Using extends /layouts/index in a view would throw the following; the "basedir" option is required to use includes and extends with "absolute" paths.
I'm not looking to use relative paths, since this quickly becomes very messy. E.g. extends ../../../layouts/index
From what I can tell, you can achieve the same functionality as /layouts/index with just using layout/index so long as layout is a folder in your templates/views directory.
I've set up a git repo as a working example so you can test it out yourself and see if I need to go in more depth about anything.
EDIT 6/27/2019:
Thank you, I misunderstood your initial question.
With creating and express based application, you can send an express server to the NestFactory to use that server instance instead of having Nest create a plain instance for you. From here you can set up the express server as you normally would and get the desired functionality. I've modified the git repo to be able to test the scenario better and believe this is what you are looking for.
My main.ts
import { NestFactory } from '#nestjs/core';
import { NestExpressApplication, ExpressAdapter } from '#nestjs/platform-express';
import * as express from 'express';
import { AppModule } from './app.module';
import { join } from 'path';
async function bootstrap() {
// Creating and setting up the express instanced server
const server = express();
server.locals.basedir = join(__dirname, '..', 'views');
// Using the express server instance in the nest factory
const app = await NestFactory.create<NestExpressApplication>(AppModule, new ExpressAdapter(server));
app.useStaticAssets(join(__dirname, '..', 'public'));
app.setBaseViewsDir(join(__dirname, '..', 'views'));
app.setViewEngine('pug');
await app.listen(3000);
}
bootstrap();
Overall the folder set up is like so
src
|-app.controller.ts
|-app.module.ts
|-app.service.ts
|-main.ts
views
|-hello
|-home.pug
|-message
|-message.pug
|-templates
|-layout.pug
And the beginning of my home.pug and message.pug files is extends /templates/layout
After looking around through the documentation, NestJS uses an express under the hood, and gives you access to the underlying instance with getHttpAdapter().getInstance().
Keeping that in mind, we can set the basedir as follows;
const express = server.getHttpAdapter().getInstance();
express.locals.basedir = join(__dirname, 'templates');

How can my client get application configuration from the server when using Webpack?

I'm adding Webpack to a Node/Express app that previously used RequireJS. When the client needed some configuration from the server, we previously used a custom Express route that retrieved specific configs as JSON:
server/index.js - Set up Express routes for config files
const app = express();
const configRouter = express.Router();
configRouter.get('/some-config.json', (req, res) => {
const someConfig = {
prop1: getProp1(),
prop2: getProp2()
}
res.json(someConfig);
}
app.use('/config', configRouter);
client/controller.js - Use/config/some-config.json during initialization
define(['text!/config/some-config.json'], function(SomeConfig) {
// do something with SomeConfig
});
But removing RequireJS means I can no longer retrieve the JSON this way as a dependency. And it's not static JSON either, so it's not as simple as just placing it alongside client code and importing it.
So what is the best way to do this with Webpack? Any help greatly appreciated. Thanks!

Having control flow issue with mongoose model's find

I'm completely new to node and it's frameworks Koa and express. I've a mongoose model called Drawing and a router module for that.
Problem is with express routers I was able the get the data from database using Drawing.find method but with Koa, control is not even going into Drawing.find. And I'm not able to get the data at all. Please find the following related code and help me understand the things better.
This is my router module
import * as Router from "koa-router";
import Drawing from "../../models/drawing";
function getRoutesForDrawing(): Router {
console.log("Inside getRoutes for drawing");
let route = new Router();
route.get("/drawing", function(context,next) {
console.log("Inside /drawing");
Drawing.find(function(err,drawings) {
console.log("Not gettig executed");
context.body = "Welcome";
});
//context.body = "Welcome";
});
}
export default getRoutesForDrawing();
And the model is
import mongoose = require("mongoose");
export interface IDrawing extends mongoose.Document {
drawingId:Number,
drawingName:String,
updatedOn:Date,
updatedBy:Number
};
export const DrawingSchema = new mongoose.Schema({
drawingId:Number,
drawingName:String,
updatedOn:Date,
updatedBy:Number
});
const Drawing = mongoose.model<IDrawing>('Drawing', DrawingSchema);
export default Drawing;
As you can see in my router module, the control is actually coming for /drawing and it's printing in console "Inside /drawing" but then control isn't coming to Drawing.find. I'm getting difficulty in understanding this.
It's a little bit hard to figure out what's going on because it looks like you have problems all over the place. Let me point out the things that stand out:
getRoutesForDrawing is declared to return a router and doesn't return anything
Koa routes are not like express. In particular they are not callback based. They take either generator functions (Koa 1.x) or async functions (Koa 2.x). You seem to expect that it's wanting a callback function which won't work. Assuming koa 2.x, its router.get('/drawing', async(context) => {...});
Assuming koa 2.x, you need to await the result of the mongoose methods, e.g. context.body = await Drawing.find({})

Router is not defined in KOA2

I have two files, one of them is the app.js and the otherone is api.js.
In the first file I have :
app.use(setHeader)
app.use(api.routes())
app.use(api.allowedMethods())
And in api.js I have:
import KoaRouter from 'koa-router';
const api = new Router();
//Validatekey
const validateKey = async (ctx, next) => {
const { authorization } = ctx.request.headers;
console.log(authorization);
if (authorization !== ctx.state.authorizationHeader) {
return ctx.throw(401);
}
await next();
}
api.get('/pets', validateKey, pets.list);
When I run the project a error message is throw: Router is not defined.
But If I write both files together, the application go fine.
Anybody knows the problem?
I have solved with var Router = require('koa-router')
The import is currently not implemented in nodejs, neither is it supported in the latest ES2015(ES6).
You will need to use a transpiler like Babel to use import in code.I advice that avoid transpiler as it cause performance issues on production just go with require and it will work.
Obviously Nodejs does not support import / export syntax and using require will solve your problem.
However it is possible to make import work on Node.js by using babel transformers.
Look the following answer for more information https://stackoverflow.com/a/37601577/972240

Resources