Repository navigation
Fix strict mode for caught optional peer imports - #2218
Conversation
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
webpro
left a comment
There was a problem hiding this comment.
Thanks for picking this up, Jay, the scope is right: a directly awaited import() inside try with a catch, nothing else. The implementation reuses IMPORT_FLAGS.OPTIONAL though, and that flag already means "no error if not resolved" for new URL(x, import.meta.url) and /// <reference path>. Reusing it changes behavior in both directions, and the new fixture never reaches the code that implements the policy. Details inline.
Suggested shape for the next round:
- Add a separate
CAUGHTflag inIMPORT_FLAGSand leaveOPTIONALuntouched. - Set it only when the
ImportExpressionis the directargumentof anAwaitExpression. - Pass it through
DependencyReferenceOptionsand letDependencyDeputy.isInDependenciesaccept optional peers when strict and caught, so@typesattribution and the default mode stay as they are. Then theanalyze.tschange is not needed. - Track try protection in the walker with the existing
TryStatementand:exithooks instead of re-walking the block. - Install
optional-peerin the fixture'snode_modules(aspeer-dependencies-optional-strict-unreferenceddoes), assert counters, and add regressions for a caught import of an unlisted package and of a missing local file.
commit: |
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
webpro
left a comment
There was a problem hiding this comment.
Thanks for the quick turnaround, this is much closer. The separate CAUGHT flag, the deputy-owned policy, the direct-argument await check and the stack-based try tracking all do what they should, and my earlier probes match main again. Two things remain, and the first one is what #2214 is about: const mod = await import('pg') inside try/catch is still unlisted in strict mode. The other is that the new URL case was turned into a new policy instead of being left as it was. Details inline, plus two branches that turned out to be unnecessary and can go.
Optional: the strict mode section in packages/docs/src/content/docs/features/production-mode.md could mention that an optional peer is accepted when its awaited import() is wrapped in try/catch.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
webpro
left a comment
There was a problem hiding this comment.
All five points from the last round are addressed, thanks. The declarator forms go through the try stack, OPTIONAL is back to its original meaning, the two redundant branches are gone, and the fixtures are precise. My probe set against main shows default mode unchanged everywhere and strict mode changing only for the caught forms. Two small things are left before this can go in: a formatting failure in walk.ts that CI will flag, and Promise.all being accepted in only one of its forms. Both inline.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
webpro
left a comment
There was a problem hiding this comment.
Thanks for the quick follow-up! Both points are fixed: the formatting check passes, and an awaited Promise.all is now caught in the statement, return and assignment forms too, with the fixture covering the statement form next to the destructured one. Default mode is still unchanged, and strict mode only changes for the caught forms.
One more change before merging, see the inline comment. I also noticed the commits are co-authored by Claude Haiku 5.5. The walker is core logic that every Knip run goes through, so for changes like this please use a stronger model and review its output closely before pushing.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Signed-off-by: jay23606 <4602056+jay23606@users.noreply.github.com>
webpro
left a comment
There was a problem hiding this comment.
Thanks for the refactor! getPromiseAllElements is now the single owner of the check, both call sites use it without changing behavior, and the walker's hot path is the same as before. Looks good to me.
|
π This pull request is included in v6.44.0. See Release 6.44.0 for release notes. Using Knip in a commercial project? Please consider becoming a sponsor. |
Summary
new URL()optional peer behavior.Tests
bun test test/dependencies/peer-dependencies-optional-strict.test.tsβ 13 passed.pnpm run buildβ passed.pnpm run lintβ passed.git diff --checkβ passed.Not verified
Fixes #2214
π€ Generated with Claude Code