Tsoa: Uncertainty in route paths for express template (and possibly for others)

Created on 30 Aug 2017  路  2Comments  路  Source: lukeautry/tsoa

This line of code
app.{{method}}('{{../../basePath}}/{{../path}}{{path}}'
in _src/routeGeneration/templates/express.ts_ template adds hardcoded / between base path and controller path.
Additionally this line of code
this.path = decoratorArgument ? `/${decoratorArgument.text}` : '';
in _src/metadataGeneration/methodGenerator.ts_ adds hardcoded / as prefix to every action path.

So if i have base path /api/v2 and

@Route()
export class LoginController {
    @Post('login')
    public async login(...): Promise<...> { ... }
}

generated route will be

app.post('/api/v2//login',
        function(request: any, response: any, next: any) {
            ...
        });

As you can see there is a double / in the path because of hardcoded symbols mentioned above.
Note that Swagger doc gets generated fine though.
This makes /api/v2//login endpoint working instead of /api/v2/login, call to latter returns 404.
Some servers are ignoring that and probably Express can ignore as well, but it would be great if TSOA can generate normal routes which are fully working on any server.

Here is the possible way to solve the problem:
1) Remove hardcoded / in code mentioned above.
2) Normalise all route paths to avoid redundant or missing / signs, possible way to do this shown below in the modified part of code from _src/routeGeneration/routeGenerator.ts_

/**
     * Removes all '/', '\', and spaces at the beginning and at the end of the path
     * Adds prefix and suffix if supplied
     */
    function normalisePath(pathStr: string, withPrefix?: string, withSuffix?: string): string {
      if(!pathStr || typeof pathStr !== 'string') {
        return pathStr;
      }
      let normalised = pathStr.replace(/^[/\\ ]+|[/\\ ]+$/g, '');
      normalised = withPrefix ? withPrefix + normalised : normalised;
      normalised = withSuffix ? normalised + withSuffix : normalised;
      return normalised
    }

    return routesTemplate({
      authenticationModule,
      basePath: this.options.basePath === '/' ? '' : normalisePath(this.options.basePath as string, '/'),
      canImportByAlias,
      controllers: this.metadata.controllers.map(controller => {
        return {
          actions: controller.methods.map(method => {
            const parameterObjs: { [name: string]: TsoaRoute.ParameterSchema } = {};
            method.parameters.forEach(parameter => {
              parameterObjs[parameter.parameterName] = this.buildParameterSchema(parameter);
            });

            return {
              method: method.method.toLowerCase(),
              name: method.name,
              parameters: parameterObjs,
              path: normalisePath(pathTransformer(method.path), '/'),
              security: method.security,
            };
          }),
          modulePath: this.getRelativeImportPath(controller.location),
          name: controller.name,
          path: normalisePath(controller.path, '/'),
        };
      }),
      environment: process.env,
      iocModule,
      models: this.buildModels(),
      useSecurity: this.metadata.controllers.some(
        controller => controller.methods.some(method => !!method.security.length),
      ),
    });

3) Normalise paths in swagger doc same way as for routes.

Fix looks pretty simple.

Thank you for making this great framework!

bug express-router

Most helpful comment

All 2 comments

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jeremyVignelles picture jeremyVignelles  路  3Comments

jfrconley picture jfrconley  路  3Comments

lonix1 picture lonix1  路  5Comments

picturelink picture picturelink  路  5Comments

rustam-crunch picture rustam-crunch  路  5Comments