Search code examples
javascriptnode.jstypescripttypeorm

typeorm cli won't await the exported async method from ormconfig.ts


Typeorm should be able to await this export as in this file. and it's also stated in this issue. For some reason, it's not working.

// src/db/ormconfig.ts

import {
  Entity1, Entity2
} from '@entity/internal';
import { getSecret } from '@utils/SystemManager';
import Logger from '@utils/Logger';

const getConnectionOptions = async () => {
  const USERNAME = await getSecret('username');
  const PASSWORD = await getSecret('password');

  const {
    RDS_DB_INSTANCE_URL,
    RDS_DB_INSTANCE_PORT,
    RDS_DB_NAME,
  } = process.env;

  Logger.info(
    'Username: (%s) Password: (%s) InstanceURL: (%s) InstancePort: (%s) DBName: (%s)',
    USERNAME,
    PASSWORD,
    RDS_DB_INSTANCE_URL,
    RDS_DB_INSTANCE_PORT,
    RDS_DB_NAME,
  );

  const config = {
    name: 'default',
    type: 'postgres',
    port: Number(RDS_DB_INSTANCE_PORT),

    // this have to be false on production as it might drop the data
    synchronize: false,
    // migrationsRun: true,
    logging: true,
    host: RDS_DB_INSTANCE_URL,
    username: USERNAME,
    database: RDS_DB_NAME,
    password: PASSWORD,
    // TODO: set the naming strategy
    // namingStrategy: new SnakeNamingStrategy(),
    entities: [
      Entity1, Entity2,
    ],
    migrations: [`${__dirname}/migration/**/*.ts`],
    subscribers: [`${__dirname}subscriber/**/*.ts`],
    cli: {
      entitiesDir: 'src/entity',
      migrationsDir: 'src/migration',
      subscribersDir: 'src/subscriber',
    },
  };

  if (PASSWORD) {
    Object.assign(config, {
      password: PASSWORD,
    });
  }

  return config;
};

module.exports = getConnectionOptions;

and command I test is:

node --require ts-node/register --require tsconfig-paths/register ./node_modules/typeorm/cli.js --config ./src/db/ormconfig.ts

The output is:

Error during migration run:
TypeORMError: Cannot find connection default because its not defined in any orm configuration files.
    at new TypeORMError (C:\Users\ahmed\Desktop\manjaro\src\error\TypeORMError.ts:7:9)
    at ConnectionOptionsReader.<anonymous> (C:\Users\ahmed\Desktop\manjaro\src\connection\ConnectionOptionsReader.ts:56:19)
    at step (C:\Users\ahmed\Desktop\manjaro\node_modules\typeorm\node_modules\tslib\tslib.js:143:27)
    at Object.next (C:\Users\ahmed\Desktop\manjaro\node_modules\typeorm\node_modules\tslib\tslib.js:124:57)
    at fulfilled (C:\Users\ahmed\Desktop\manjaro\node_modules\typeorm\node_modules\tslib\tslib.js:114:62)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
error Command failed with exit code 1.

After some debugging and directly editing typeorm codebase in the node_modules, I found out that the connectionOptions it uses is of type "Async function" so it didn't await it. Any ideas?


Solution

  • solved in typeorm#4149 but quoted below:

    // a.ts
    const f = async () => {};
    export f;
    

    And now,

    // b.ts
    const f = await require('./a.ts');
    

    This was what's happening, I was exporting the method itself and awaiting the require assuming it will call the method and await it, however, this was not the case. This will pass an "Async function" to typeorm. This will work if:

    // b.ts
    const f = await require('./a.ts')();
    

    but this requires working inside typeorm # fail

    but we can:

    // a.ts
    const f = async () => {};
    export f();
    

    call f, so we require the f call and not f itself, so await works on it.