8
votes

I'm using NestJs to create a couple of applications and I want to move the code from a NestInterceptor for an external NPM Package so I can use the same interceptor in multiple applications.

The problem is that the same code that works when used "locally" just stop working when moved to the external package.

Here's the code for the interceptor:

import { Injectable, NestInterceptor, CallHandler, ExecutionContext } from '@nestjs/common'
import { map } from 'rxjs/operators'
import { getManager } from 'typeorm'
import jwt_decode from 'jwt-decode'

@Injectable()
export class MyInterceptor implements NestInterceptor {
  entity: any

  constructor(entity: any) {
    this.entity = entity
  }

  async intercept(context: ExecutionContext, next: CallHandler): Promise<any> {

    const request = context.switchToHttp().getRequest()

    const repository = getManager().getRepository(this.entity)

    return next.handle().pipe(map((data) => data))
  }
}

Here's a given controller:

import { myInterceptor } from "../src/interceptors/interceptor.ts";

@UseInterceptors(new CompanyIdInterceptor(User))
export class UserController {
}

This works fine, but if a move the file to an external NPM package and import from it like this:

import { myInterceptor } from "mynpmpackage";

I get the following error:

[Nest] 24065   - 04/18/2019, 10:04 AM   [ExceptionsHandler] Connection "default" was not found. +26114ms
ConnectionNotFoundError: Connection "default" was not found.
    at new ConnectionNotFoundError (/home/andre/Services/npm-sdk/src/error/ConnectionNotFoundError.ts:8:9)
    at ConnectionManager.get (/home/andre/Services/npm-sdk/src/connection/ConnectionManager.ts:40:19)

Any ideas, on what causes this and how to solve it?

2
Do you use ts-node? Be careful, as within a node module, you need to have your TypeOrm connection defined for *.js files (entities and all), in ts-node it works with *.ts files. - zenbeni
I do use ts-node, but in my Typeorm setup i do count for js files: entities: [ ${path.join(appRootPath.path, '{src,dist}')}/**/*.entity{.ts,.js}, ], - André Oliveira
@AndréD.Oliveira When you move the interceptor to an external package, do you have typeorm as a dependency or a peer dependency? - shusson
@shusson I have typeOrm as both, dependency and peer dependency. - André Oliveira
@AndréD.Oliveira try making typeorm only a peer dependency in the external package - shusson

2 Answers

0
votes

This might not be your problem exactly, but I had a similar problem when moving things to external packages with TypeORM. Make sure all packages from parent project are using the same version of the TypeORM package.

In my case, using yarn why typeorm showed me two different versions were being installed. One of them was used to register the entities, while the framework connected to the SQL database using another version, generating this clash.

Check your versions using yarn why [pkg-name] or if you're using NPM, try npx npm-why [pkg-name] or install globally from https://www.npmjs.com/package/npm-why.

0
votes

After verifying TypeOrm versions is same in both the packages i.e- external package and consumer repository as mentioned by @Luís Brito still issue persist then issue could be-

Basically when we create an external package - TypeORM tries to get the "default" connection option, but If not found then throws an error:

ConnectionNotFoundError: Connection "default" was not found.

We can solve this issue by doing some kind of sanity check before establishing a connection - luckily we have .has() method on getConnectionManager().

import { Connection, getConnectionManager, getConnectionOptions, 
  createConnection, getConnection, QueryRunner } from 'typeorm';
    
    async init() {
    let connection: Connection;
    let queryRunner: QueryRunner;

     if (!getConnectionManager().has('default')) {
        const connectionOptions = await getConnectionOptions();
        connection = await createConnection(connectionOptions);
      } else {
        connection = getConnection();
      }

    queryRunner = connection.createQueryRunner(); 
 }

Above is a quick code-snippet which was the actual root cause for this issue but If you are interested to see complete working repositories (different example) -

  • External NPM Package :
  • Consumer of above package : nest-typeorm-postgre (specific files- package.json, src/countries/countries.service.ts & countries.module.ts)