-
Notifications
You must be signed in to change notification settings - Fork 221
Description
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:
typeorm/lib/typeorm.providers.ts
Lines 29 to 38 in 0a6c085
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.
typeorm/lib/common/typeorm.utils.ts
Lines 24 to 41 in 0a6c085
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
.
typeorm/lib/common/typeorm.utils.ts
Lines 61 to 71 in 0a6c085
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:
typeorm/lib/common/typeorm.utils.ts
Line 33 in 0a6c085
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: