Skip to content

Injecting custom repositories that use the default connection is broken on 6.1.0 #109

@brianmcd

Description

@brianmcd

I'm submitting a...


[x] Regression 
[ ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Current behavior

On @nestjs/typeorm 6.1.0, if you use a custom repository and the default connection, the repository cannot be injected anywhere. 6.0.0 did not have this issue.

The app crashes with:

[Nest] 28596   - 04/30/2019, 3:50 PM   [ExceptionHandler] Nest can't resolve dependencies of the AppController (?). Please make sure that the argument at index [0] is available in the AppModule context. +11ms
Error: Nest can't resolve dependencies of the AppController (?). Please make sure that the argument at index [0] is available in the AppModule context.
    at Injector.lookupComponentInExports (/home/brianmcd/work/typeorm-issue/node_modules/@nestjs/core/injector/injector.js:180:19)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
    at process.runNextTicks [as _tickCallback] (internal/process/next_tick.js:51:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:777:11)
    at Object.<anonymous> (/home/brianmcd/work/typeorm-issue/node_modules/ts-node/src/bin.ts:157:12)
    at Module._compile (internal/modules/cjs/loader.js:721:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:732:10)
    at Module.load (internal/modules/cjs/loader.js:620:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:560:12)
    at Function.Module._load (internal/modules/cjs/loader.js:552:3)
 1: 0x946a50 node::Abort() [/home/brianmcd/.nvm/versions/node/v11.7.0/bin/node]
 2: 0x9b34f9  [/home/brianmcd/.nvm/versions/node/v11.7.0/bin/node]
 3: 0xb97dca  [/home/brianmcd/.nvm/versions/node/v11.7.0/bin/node]
 4: 0xb98979 v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*) [/home/brianmcd/.nvm/versions/node/v11.7.0/bin/node]
 5: 0x2f2a22ecfc5d 
Aborted (core dumped)

Expected behavior

Custom repositories should work.

Minimal reproduction of the problem with instructions

https://github.com/brianmcd/nest-typeorm-bug

I think what is happening is that custom repositories are getting setup with a malformed injection token.

The repository provider token is created here:

const repositories = (entities || []).map(entity => ({
provide: getRepositoryToken(entity, connection),
useFactory: (connection: Connection) => {
if (entity.prototype instanceof Repository) {
return getCustomRepository(connection, entity) as any;
}
return getRepository(connection, entity) as any;
},
inject: [getConnectionToken(connection)],
}));

With a default connection, this calls getRepositoryToken(entity, DEFAULT_CONNECTION_NAME).

getRepositoryToken calls getConnectionToken(connection) on line 31.

export function getRepositoryToken(
entity: Function,
connection: Connection | ConnectionOptions | string = DEFAULT_CONNECTION_NAME,
) {
if (isNullOrUndefined(entity)) {
throw new CircularDependencyException('@InjectRepository()');
}
const connectionToken = getConnectionToken(connection);
const connectionPrefix =
connectionToken === DEFAULT_CONNECTION_NAME ? '' : `${connectionToken}_`;
if (
entity.prototype instanceof Repository ||
entity.prototype instanceof AbstractRepository
) {
return `${connectionPrefix}${getCustomRepositoryToken(entity)}`;
}
return `${connectionPrefix}${entity.name}Repository`;
}

For the default connection, getConnectionToken returns Connection, not DEFAULT_CONNECTION_NAME.

export function getConnectionToken(
connection: Connection | ConnectionOptions | string = DEFAULT_CONNECTION_NAME,
): string | Function | Type<Connection> {
return DEFAULT_CONNECTION_NAME === connection
? Connection
: 'string' === typeof connection
? `${connection}Connection`
: DEFAULT_CONNECTION_NAME === connection.name || !connection.name
? Connection
: `${connection.name}Connection`;
}

The bug manifests itself here:

connectionToken === DEFAULT_CONNECTION_NAME ? '' : `${connectionToken}_`;

connectionToken is the class Connection, which isn't DEFAULT_CONNECTION_NAME, so the prefix is set to a stringified version of the Connection constructor. You end up with a very weird injection token, which doesn't match the Repository's name, so the dependency can't be found when you try to inject it.

Environment


@nestjs/typeorm version: 6.1.0

 
For Tooling issues:
- Node version: XX  
- Platform:  Linux 

Others:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions