Skip to content

Conversation

@CarlosLozanoHealthCaters
Copy link
Collaborator

Closes #356

Please take a look! I will include tests and modify the documentation when I have 5 minutes.

@avaly
Copy link
Collaborator

avaly commented Dec 14, 2022

Hi @CarlosLozanoHealthCaters!

We appreciate your time on opening this PR and writing all the tests.

We do have some hesitation on introduction the requirement that all projections should be defined as const. We don't see the problem this is solving (being able to send _id: 0) as such a common use case in real world applications (of course we're biased :)) to warrant this breaking change.

If you could refactor the code to work without this requirement, it'd make accepting this PR much easier.

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

CarlosLozanoHealthCaters commented Dec 14, 2022

Hi @avaly

Thanks for your comment.

Although the original problem was suppressing _id, the current change goes further and provides a better alignment with MongoDB projections. In MongoDB, if you want to get all the fields except one, you can put that field with 0 and then the operation will return all fields except the one you don't want. In this way, you don't need to make complex projections or worry about changes in the schema in the future. For me, having this alignment with MongoDB definition is quite interesting and something we should aim for.

About the breaking change, I was playing a bit more with the types and I could find a good solution. If developers doesn't put as const, the projection type consider that all fields defined will be returned. If they put as const, then the projection will work according to the MongoDB definition.

I think this solution brings the best of both worlds. I would like to include some doc about the new projections way if I have your approval.

Copy link
Collaborator

@avaly avaly left a comment

Choose a reason for hiding this comment

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

This looks much better! Thanks for the changes and keeping backwards compatibility with the old non-const projections.

We'll definitely need a detailed section about this in our docs. Maybe it fits in the ProjectionType section, since we link to that from all the find* methods.

src/utils.ts Outdated
Comment on lines 102 to 103
type FilterKeys<T, U> = { [P in keyof T]: T[P] extends U ? P : never }[keyof T];
type FilterProperties<T, U> = { [K in FilterKeys<T, U>]: T[K] };
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please use longer names for the generic types here. And add some newlines between each type.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done!

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

@avaly Please check my latest changes. I added also the documentation. If everything is ok, please go ahead. :)

Have you had time to test it and see it in live?

avaly
avaly previously approved these changes Dec 21, 2022
Copy link
Collaborator

@avaly avaly left a comment

Choose a reason for hiding this comment

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

This looks great! Thanks for all the work and taking our feedback!

I'll test this internally and merge this after the holidays period.

@avaly
Copy link
Collaborator

avaly commented Jan 10, 2023

@CarlosLozanoHealthCaters I just got around to trying this on our private repository and I ran into a blocker:

NODE_OPTIONS=--max-old-space-size=6144 yarn tsc
/home/avaly/dev/node_modules/typescript/lib/tsc.js:99699
                throw e;
                ^

RangeError: Maximum call stack size exceeded
    at resolveNameHelper (/home/avaly/dev/node_modules/typescript/lib/tsc.js:41771:35)
    at resolveName (/home/avaly/dev/node_modules/typescript/lib/tsc.js:41769:20)
    at resolveEntityName (/home/avaly/dev/node_modules/typescript/lib/tsc.js:42991:42)
    at getSymbolOfNameOrPropertyAccessExpression (/home/avaly/dev/node_modules/typescript/lib/tsc.js:74339:30)
    at getSymbolAtLocation (/home/avaly/dev/node_modules/typescript/lib/tsc.js:74413:32)
    at getTypeFromTypeNodeWorker (/home/avaly/dev/node_modules/typescript/lib/tsc.js:53916:34)
    at containsReference (/home/avaly/dev/node_modules/typescript/lib/tsc.js:54131:29)
    at visitNode (/home/avaly/dev/node_modules/typescript/lib/tsc.js:25136:24)
    at forEachChildInTypeReference (/home/avaly/dev/node_modules/typescript/lib/tsc.js:25349:20)
    at Object.forEachChild (/home/avaly/dev/node_modules/typescript/lib/tsc.js:25900:47)

Node.js v18.13.0

Any ideas on workarounds?

We're using [email protected]

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

@avaly Don't know why that error is being thrown in your code.

I've just run the script 'test:types' from the package.json with yarn test:types and everything is ok.

I have also tested the new papr version in our product and it's also compiling and checking all the types correctly.

Could it be caused by other piece of code?

@avaly
Copy link
Collaborator

avaly commented Jan 12, 2023

Could it be caused by other piece of code?

No. tsc runs fine on our main branch. As soon as I bring in your changes from Papr, I get the error above. It's definitely a combination of those changes in Papr and some complexity of our internal usage of Papr models.

Unfortunately, this is blocker for us and won't be able to merge this as is. I'll try to debug this in our repo when I get a chance, but I can't give you any timeline.

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

@avaly can you check now? I've simplified one of the types and most probably won't throw Maximum call stack size exceeded

@avaly
Copy link
Collaborator

avaly commented Jan 23, 2023

@CarlosLozanoHealthCaters I checked this branch now with the new commit, but I'm still getting the maximum call stack error.

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

Can you provide the tsconfig.json and package.json to check which lib are you using?

@avaly
Copy link
Collaborator

avaly commented Jan 23, 2023

We're using "typescript": "4.9.3" with this config:

{
  "compilerOptions": {
    "allowJs": true,
    "baseUrl": "./",
    "checkJs": true,
    "esModuleInterop": true,
    "lib": ["ES2020"],
    "module": "CommonJS",
    "moduleResolution": "Node",
    "noEmit": true,
    "noErrorTruncation": false,
    "noImplicitAny": false,
    "noImplicitReturns": false,
    "noImplicitThis": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "preserveWatchOutput": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "strictBindCallApply": true,
    "strictNullChecks": true,
    "strictPropertyInitialization": false,
    "target": "ESNext",
    "typeRoots": ["./@types", "./node_modules/@types"],
    "types": ["node", "jest"]
  },
  "exclude": [
    "**/*.cjs",
    "node_modules",
    "**/__tests__/*.js",
    "**/__tests__/**/*.js"
  ],
  "include": [
    "./"
  ]
}

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

Could you please check the compilation also crash if you set allowJs to false in your tsconfig?

Probably tons of errors could appear in console, but we can guess if the compilation also crash or not.

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

@avaly I created a new type StrictProjectionType to separate the old type and new type. I think it's a good approach and solution.

@avaly
Copy link
Collaborator

avaly commented Feb 6, 2023

@CarlosLozanoHealthCaters I tried this again on our repo, and initially it failed again with the same error - which puzzled me very much. I then tried to comment out your types changes and ran it again, and I got the same error.

At this point, I realized something must be off when trying to use this library from your branch. My method of testing this was that I ran yarn build in the papr git folder, and ran yarn link /path/to/papr in our private repo. This is how I test all incoming PRs to Papr (even our own contributions). For some (unknown) reason, your branch triggers this max call stack error.

So I tried a different approach: yarn pack in the papr git folder, copy the .tgz file to our private repo and use it from there.

Once I did this, your changes no longer trigger that weird error. I even went back to your
4034125 commit, and even that worked (with a few errors popping up on our end due to some generic projection types).

So we could move ahead with either approach, but if you're open to it, I would prefer going with the latest version of the separate StrictProjectionType.

@avaly
Copy link
Collaborator

avaly commented Feb 6, 2023

I think I changed my mind, so we can try to merge this without the separate strict type.

@CarlosLozanoHealthCaters if you want to revert your commits until this commit 4034125, I can run through it again and finally land this (but probably after v10 goes out #422).

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

@avaly done!

avaly
avaly previously approved these changes Feb 7, 2023
@avaly
Copy link
Collaborator

avaly commented Feb 14, 2023

@CarlosLozanoHealthCaters when you have some time, can you please rebase this on the latest main?

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

@avaly is it now correct?

@CarlosLozanoHealthCaters
Copy link
Collaborator Author

I have simplified

keyof FilterProperties<Projection, 0> | keyof FilterProperties<Projection, 1> extends never

by

keyof FilterProperties<Projection, 0 | 1> extends never

I think it will help compiler

@avaly avaly changed the title feat: suppress _id field and return all but the excluded fields in ProjectionType feat: Support excluding fields in ProjectionType Feb 15, 2023
@avaly avaly merged commit 086d8f1 into plexinc:main Feb 15, 2023
avaly added a commit that referenced this pull request Feb 16, 2023
@CarlosLozanoHealthCaters CarlosLozanoHealthCaters deleted the fix/projection-type branch May 7, 2023 07:06
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.

Wrong ProjectionType when suppressing _id field from the projection

2 participants