Skip to content

Conversation

@anton-pavlov-personal
Copy link
Contributor

@anton-pavlov-personal anton-pavlov-personal commented Apr 20, 2022

Description of change

Support async import for DataSource in CLI. Fixes #8914

Pull-Request Checklist

  • Code is up-to-date with the master branch
  • npm run format to apply prettier formatting
  • npm run test passes with this change
  • This pull request links relevant issues as Fixes #0000
  • There are new or updated unit tests validating the change
  • Documentation has been updated to reflect this change
  • The new commits follow conventions explained in CONTRIBUTING.md

@Ginden Ginden requested a review from pleerock April 21, 2022 12:39
) {
dataSourceExports.push(dataSourceFileExports[fileExport])
for (const fileExport of dataSourceFileExports) {
const awaitedFileExport = await fileExport
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't we add a check (something like if (fileExport instanceof Promise)) in order to make it more clear? also I recommend to add a comment line and explain why this change is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pleerock Sure, we can. It was decided to do so for sake of shortness (as far as await does not make (almost) any effect on non-Promise value this way).

But if it will be more clear this way, we can do like this (and the comment would be like that):

// It is necessary to await here in case of the exported async value (Promise<DataSource>).
// e.g. the DataSource is instantiated with an async factory in the source file
const awaitedFileExport = fileExport instanceof Promise 
  ? await fileExport
  : fileExport;

What do you think?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pleerock It's possible, but some people still use eg. Bluebird promises or compilation chains with Promise polyfills. There isn't any benefit in instanceof Promise checks, but only some obscure bug reports.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think awaiting doesn't introduce any overhead, as MDN states - Returns the fulfilled value of the promise, or the value itself if it's not a Promise. And even if there is any, it is too small. So I would agree with @Ginden on this one

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes so sometimes I prefer to have more code to make things more explicit / transparent and easier to understand.

@ViniciussSantos
Copy link

I have some questions about how commandUtils.loadDataSource works and how to test this new bugfix. First, I'm trying to create a test that works for the current version first before adapting it to work with the async version:

const dataSourceExports = []
for (let fileExport in dataSourceFileExports) {
    if (
        InstanceChecker.isDataSource(dataSourceFileExports[fileExport])
    ) {
        dataSourceExports.push(dataSourceFileExports[fileExport])
    }
}
  if (dataSourceExports.length === 0) {
            throw new Error(
                `Given data source file must contain export of a DataSource instance`,
            )
        }

But for some reason the InstanceChecker if statement is always false and the error is always thrown in my test and I can't seem to understand why.

Right now, my test involves a simple file exporting a dataSource instance like this:

const options: DataSourceOptions = {
    type: "postgres",
    host: "localhost",
    port: 5432,
    username: "test",
    password: "test",
    database: "test",
    synchronize: true,
    entities: [Post, Author, Category],
}
const dataSource = new DataSource(options)

module.exports = dataSource

and I'm testing it like this:

const DataSourcePath = __dirname + "/datasourceInstance"
        const response = await CommandUtils.loadDataSource(
            DataSourcePath,
        )
        expect(response).instanceOf(DataSource)

when I console.log dataSourceFileExports, I get the confirmation that it's actually a datasource instance:
image
but the instanceChecker never returns a true value. What am I doing wrong @Ginden @pleerock ?

@Ginden Ginden requested a review from pleerock June 8, 2022 08:33
@pleerock
Copy link
Member

@ViniciussSantos not sure, you might need to debug and check the data source symbol values?

@jordanmnunez
Copy link

any update on pushing this through? Looks like it is really close

@texiontech
Copy link

when will release this issue.

@Ginden Ginden mentioned this pull request Aug 2, 2022
4 tasks
@pleerock pleerock merged commit 15f90e0 into typeorm:master Aug 22, 2022
wirekang pushed a commit to wirekang/typeorm that referenced this pull request Aug 25, 2022
…#8917)

* Fix: await DataSource from export file to support async loading

* fix: prettier errors

* updated code style

Co-authored-by: Umed Khudoiberdiev <[email protected]>
@anton-pavlov-personal anton-pavlov-personal deleted the fix/8914-cli-does-not-support-async-datasource branch August 26, 2022 08:11
nordinh pushed a commit to nordinh/typeorm that referenced this pull request Aug 29, 2022
…#8917)

* Fix: await DataSource from export file to support async loading

* fix: prettier errors

* updated code style

Co-authored-by: Umed Khudoiberdiev <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CLI does not support async DataSource

8 participants