Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query operators (Like, MoreThan) don't work if used via a 3rd party library that import TypeOrm #8579

Closed
lucafaggianelli opened this issue Jan 28, 2022 · 4 comments

Comments

@lucafaggianelli
Copy link

lucafaggianelli commented Jan 28, 2022

Issue Description

I developed an NPM library to build a Typeorm find query starting from the HTTP query string (actually Koa query object...) and it works well as far as it concerns building the query object with where clause, take and skip params, etc.
But when I run the query the result is wrong and actually, the generated SQL is wrong.

After some tests, I understood that the issue is due to the way I import typeorm.
On 1 side I have my-utils-library that imports Typeorm and implements a function to build a query.
On the other side I have my HTTP app where I declare Typeorm entities, init the DB and where I also import my-utils-library to use the buildTypeormQuery() function.

Now if I just move the code for buildTypeormQuery to the main package, the issue disappears.

The same happens with several other libraries that do the same job, like https://github.com/rjlopezdev/typeorm-express-query-builder

Expected Behavior

I expect that operators just work regardless of how the library is imported.

Actual Behavior

If I run this query:

const myQuery = buildTypeormQuery(myHttpQueryString)
/*
myQuery = {
  where: {
    accountName: Like('%amazon%')
  }
}
*/
Customer.find(myQuery)

this is the executed SQL (logged by typeorm), please notice the = $1 where it should be ILIKE $1:

SELECT "Customer"."createdAt" AS "Customer_createdAt", "Customer"."updatedAt" AS "Customer_updatedAt", "Customer"."id" AS "Customer_id", "Customer"."customerName" AS "Customer_customerName", "Customer"."accountName" AS "Customer_accountName", "Customer"."accountHierarchy1" AS "Customer_accountHierarchy1", "Customer"."accountHierarchy1Name" AS "Customer_accountHierarchy1Name", "Customer"."accountHierarchy2" AS "Customer_accountHierarchy2", "Customer"."accountHierarchy2Name" AS "Customer_accountHierarchy2Name", "Customer"."accountHierarchy3" AS "Customer_accountHierarchy3", "Customer"."accountHierarchy3Name" AS "Customer_accountHierarchy3Name", "Customer"."tier" AS "Customer_tier" FROM "customers" "Customer"
WHERE "Customer"."accountName" = $1 LIMIT 30 -- PARAMETERS: [{"_type":"ilike","_value":"%amazo%","_useParameter":true,"_multipleParameters":false}]

Steps to Reproduce

You need 2 npm packages, in 1 package run the following

Customer.find(buildQuery())

In another package implement the buildQuery() function that returns a TypeOrm query, or use a library like https://github.com/rjlopezdev/typeorm-express-query-builder

const buildQuery = () => ({
  where: {
    accountName: Like('%amazon%')
  }
})

My Environment

Dependency Version
Operating System Mac OS 12.0.1
Node.js version v16.13.0
Typescript version 4.4.4
TypeORM version 0.2.41

Additional Context

Relevant Database Driver(s)

DB Type Reproducible
aurora-data-api no
aurora-data-api-pg no
better-sqlite3 no
cockroachdb no
cordova no
expo no
mongodb no
mysql no
nativescript no
oracle no
postgres yes
react-native no
sap no
sqlite no
sqlite-abstract no
sqljs no
sqlserver no

Are you willing to resolve this issue by submitting a Pull Request?

  • ✖️ Yes, I have the time, and I know how to start.
  • ✅ Yes, I have the time, but I don't know how to start. I would need guidance.
  • ✖️ No, I don’t have the time, but I can support (using donations) development.
  • ✖️ No, I don’t have the time and I’m okay to wait for the community / maintainers to resolve this issue.
@Ginden
Copy link
Collaborator

Ginden commented Jan 28, 2022

This seem to be very similar to issue #6727

I've got similar issues in past, but I couldn't really pinpoint them to specific pattern in code.

CC @imnotjames

@lucafaggianelli
Copy link
Author

Yep that seems it!

Given that I'm able to reproduce it 100% of the time and appears only due to the import of Typeorm via another package, I may guess that in the function that builds the query, there's some check on the Operator type but this check fails as there are 2 Operator types imported from 2 different instances of typeorm lib... just a guess

@Ginden
Copy link
Collaborator

Ginden commented Jan 28, 2022

this check fails as there are 2 Operator types imported from 2 different instances of typeorm lib... just a guess

Your library should use peer dependencies then: https://nodejs.org/es/blog/npm/peer-dependencies/

@lucafaggianelli
Copy link
Author

OK so I understood what's going on. Indeed I was already using peer dependencies, but during the development, I was linking the library package to the app package (withyarn link) and it seems that due to the linking process, I ended up with 2 instances of Typeorm, 1 in the main app and the other in the linked package. If I install the package instead of linking it, the issue doesn't occur.

I ended up using https://github.com/wclr/yalc during development to avoid issues due to package linking.

So, in my opinion, there are 2 options to close this issue:

  1. make the query builder more robust against multiple instances of Typeorm
  2. add a warning in the usage/installation of Typeorm saying that there should always exist 1 instance of the library, so use peer deps, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants