fix: monorepo's wrong auth error
Change
- add getCurrentNodeAndReachableDataModelsAndTypeDefs
When performing auth() expression validation, the current approach is to retrieve the relevant decl data from all documents.
However, this is prone to errors in a monorepo, as described in the issue.
Therefore, my improvement is to start from the current document, retrieve all documents corresponding to the imports, and then parse them.
related issue https://github.com/zenstackhq/zenstack/issues/1532
๐ Walkthrough
Walkthrough
Refactoring of data-model resolution logic to use a narrower scope. New utility functions added to resolve data models from the current node and reachable documents, replacing the broader all-loaded-documents approach. Call sites updated to use the new functions.
Changes
| Cohort / File(s) | Summary |
|---|---|
Utility function additions packages/schema/src/utils/ast-utils.ts |
Added getCurrentNodeAndReachableDataModelsAndTypeDefs() to compute DataModel/TypeDef declarations reachable from a given node's document. Added getAllLoadedAndReachableDataModelsAndTypeDefs() to return all loaded declarations with optional transitive import merging. |
Call site updates packages/schema/src/language-server/zmodel-linker.ts, packages/schema/src/language-server/zmodel-scope.ts |
Updated imports and function calls to replace getAllLoadedAndReachableDataModelsAndTypeDefs() with getCurrentNodeAndReachableDataModelsAndTypeDefs(), passing the current node and containing data model as arguments. Minor whitespace cleanup in zmodel-scope.ts. |
Estimated code review effort
๐ฏ 2 (Simple) | โฑ๏ธ ~8 minutes
- Straightforward utility function additions with clear, single-purpose logic
- Consistent refactoring pattern applied across two call sites
- Import reorganization is minimal and mechanical
- Functions follow established patterns for traversing Langium documents and data model trees
Pre-merge checks and finishing touches
โ Failed checks (1 warning)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Docstring Coverage | โ ๏ธ Warning | Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
โ Passed checks (2 passed)
| Check name | Status | Explanation |
|---|---|---|
| Title check | โ Passed | The title 'fix: monorepo's wrong auth error' directly addresses the main change, which is fixing auth() validation errors in monorepo environments by improving data model resolution scope. |
| Description check | โ Passed | The description clearly explains the problem (auth validation issues in monorepos) and the solution (implementing getCurrentNodeAndReachableDataModelsAndTypeDefs to start from current document), which aligns with the changeset. |
โจ Finishing touches
- [ ] ๐ Generate docstrings
๐งช Generate unit tests (beta)
- [ ] Create PR with unit tests
- [ ] Post copyable unit tests in a comment
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.
Comment @coderabbitai help to get the list of available commands and usage tips.
@ymc9 @jasonmacdonald
Excuse me, could you please review my changes? Do you think they are reasonable, and would such changes cause any disruptive changes?
Hi @cqh963852 , thanks for making this PR!
The original design was for a convenience concern. Consider the following example:
model Post {
...
@@allow('all', auth().role == 'ADMIN')
}
The Post model has no relation to User, thus doesn't import the zmodel that contains User, the current design still resolves auth() by checking all loaded models, even those not imported. With a design change, the user would need to explicitly import it in this case, if I understand it correctly.
For your specific problem, does the resolution issue only happen inside IDE, or with the zenstack generate as well?
For your specific problem, does the resolution issue only happen inside IDE, or with the zenstack generate as well?
Only happened inside vscode. ZenStack Generate works correctly.
the current design still resolves auth() by checking all loaded models
Could we adjust this design? maybe
- If the user has specified entries, Load only documents with intersecting paths; otherwise, load from all documents.
{
"zmodel.entries":["package/abc", "package/def"]
}
package/abc/post.zmodel ,only load package/abc's documents
model Post {
...
@@allow('all', auth().role == 'ADMIN')
}
package/def/post.zmodel ,only load package/def's documents
model Post {
...
@@allow('all', auth().role == 'ADMIN')
}
the current design still resolves auth() by checking all loaded models
Could we adjust this design? maybe
- If the user has specified entries, Load only documents with intersecting paths; otherwise, load from all documents.
{ "zmodel.entries":["package/abc", "package/def"] }package/abc/post.zmodel ,only load package/abc's documents
model Post { ... @@allow('all', auth().role == 'ADMIN') }package/def/post.zmodel ,only load package/def's documents
model Post { ... @@allow('all', auth().role == 'ADMIN') }
Absolutely! I think similar ideas were brought up before but never got implemented. The setting only needs to be recognized by the language server to limit the transitive closure built for resolving auth().