-
-
Notifications
You must be signed in to change notification settings - Fork 91
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
feat: allow using a type as auth model #1841
Conversation
📝 WalkthroughWalkthroughThis pull request introduces various modifications to the grammar definitions and validation mechanisms within the ZModel language specification. Key changes include updates to the Changes
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (16)
packages/schema/src/language-server/utils.ts (1)
32-37
: LGTM with minor documentation suggestions.The implementation is clean and properly typed. Consider enhancing the JSDoc with:
- An example showing typical usage
- Description of what constitutes a "resolvable member"
Example enhancement:
/** * Checks if the given node can contain resolvable members. + * + * @example + * if (isMemberContainer(node)) { + * // node is guaranteed to be either DataModel or TypeDef + * // and can contain resolvable members like fields or properties + * } */packages/schema/src/language-server/validator/typedef-validator.ts (1)
17-19
: Consider adding type-specific attribute validationWhile the implementation is clean, consider adding explicit validation to ensure that the attributes are compatible with type definitions. According to the AI summary, attributes applied to type definitions should have the
@@@supportTypeDef
attribute.Consider updating the implementation to include type-specific validation:
private validateAttributes(typeDef: TypeDef, accept: ValidationAcceptor) { - typeDef.attributes.forEach((attr) => validateAttributeApplication(attr, accept)); + typeDef.attributes.forEach((attr) => { + validateAttributeApplication(attr, accept); + // Validate that the attribute supports type definitions + validateTypeDefAttributeSupport(attr, accept); + }); }packages/schema/src/language-server/validator/schema-validator.ts (1)
39-40
: LGTM with suggestions for improved clarityThe changes correctly implement the ability to validate both data models and types for
@@auth
attribute. However, a few improvements could make the code more maintainable:
- The error message could be more precise to reflect that either a type or model can have
@@auth
- The boolean parameter in
getDataModelAndTypeDefs(model, true)
could be more explicitConsider applying these improvements:
const decls = getDataModelAndTypeDefs(model, true); const authModels = decls.filter((d) => isDataModel(d) && hasAttribute(d, '@@auth')); if (authModels.length > 1) { - accept('error', 'Multiple `@@auth` models are not allowed', { node: authModels[1] }); + accept('error', 'Multiple `@@auth` declarations (models or types) are not allowed', { node: authModels[1] }); }Also consider making the boolean parameter more explicit:
-const decls = getDataModelAndTypeDefs(model, true); +const includeTypes = true; // Include both models and type definitions +const decls = getDataModelAndTypeDefs(model, includeTypes);tests/integration/tests/enhancements/json/validation.test.ts (4)
40-56
: LGTM: Well-structured test for policy rule validationThe test effectively verifies that direct member access is disallowed in policy rules. Consider making the error message more user-friendly by including context about why the access is not allowed.
- ).resolves.toContain(`Could not resolve reference to MemberAccessMember named 'age'.`); + ).resolves.toContain(`Direct member access 'profile.age' is not allowed in policy rules. Use 'auth()' to access authenticated user's data.`);
58-74
: Consider adding negative test cases for auth member accessWhile the test correctly verifies that valid auth member access works, consider adding test cases for:
- Invalid auth member paths
- Nested invalid members
- Type mismatches in the access chain
Example additional test case:
it('fails on invalid auth member accesses in policy rules', async () => { await expect( loadModelWithError(` type Profile { age Int @gt(0) } model User { id Int @id @default(autoincrement()) profile Profile @json @@allow('all', auth().profile.invalidField > 18) } `) ).resolves.toContain('Could not resolve member "invalidField"'); });
76-134
: LGTM: Comprehensive collection access validationThe tests effectively cover both normal and authenticated collection access scenarios. However, consider adding test cases for:
- Nested collection access (e.g.,
auth().profile.roles?[org.name == 'X']
)- Invalid filter conditions
- Type mismatches in filter expressions
Line range hint
1-158
: Consider adding tests for edge casesThe test suite is well-structured and covers the main functionality. Consider adding tests for:
- Deeply nested type structures
- Circular type references
- Mixed usage of primitive and complex types
- Error cases with malformed JSON data
packages/schema/src/utils/ast-utils.ts (1)
307-312
: LGTM with a minor documentation suggestion.The function implementation correctly handles both data models and type definitions. Consider enhancing the JSDoc comment to be more descriptive about the return type.
/** - * Gets all data models and type defs from all loaded documents + * Gets all data models and type definitions from all loaded documents + * @returns An array of DataModel and TypeDef nodes from all loaded documents */packages/sdk/src/utils.ts (3)
54-64
: LGTM! Consider enhancing the JSDoc.The implementation correctly filters both DataModel and TypeDef declarations. Consider documenting the
includeIgnored
parameter in the JSDoc to maintain consistency with other functions./** * Gets data models and type defs in the ZModel schema. + * @param model The ZModel schema + * @param includeIgnored When true, includes models marked with @@ignore */
474-479
: LGTM! Consider adding error handling.The function has been appropriately renamed and updated to support both DataModel and TypeDef as auth declarations. The implementation maintains the existing logic while expanding its scope.
Consider adding null checks for undefined refs:
export function getAuthDecl(decls: (DataModel | TypeDef)[]) { + if (!decls?.length) { + return undefined; + } let authModel = decls.find((m) => hasAttribute(m, '@@auth')); if (!authModel) { authModel = decls.find((m) => m.name === 'User'); } return authModel; }
Line range hint
499-517
: Add null check for modelIdAttr args.The function has been correctly updated to support both DataModel and TypeDef. However, there's a potential null reference when accessing
modelIdAttr.args[0]
.Apply this fix:
export function getIdFields(decl: DataModel | TypeDef) { const fields = isDataModel(decl) ? getModelFieldsWithBases(decl) : decl.fields; const fieldLevelId = fields.find((f) => f.attributes.some((attr) => attr.decl.$refText === '@id')); if (fieldLevelId) { return [fieldLevelId]; } else { // get model level @@id attribute const modelIdAttr = decl.attributes.find((attr) => attr.decl?.ref?.name === '@@id'); - if (modelIdAttr) { + if (modelIdAttr?.args?.[0]?.value) { // get fields referenced in the attribute: @@id([field1, field2]]) if (!isArrayExpr(modelIdAttr.args[0].value)) { return []; } const argValue = modelIdAttr.args[0].value; return argValue.items .filter((expr): expr is ReferenceExpr => isReferenceExpr(expr) && !!getDataModelFieldReference(expr)) .map((expr) => expr.target.ref as DataModelField); } } return []; }packages/schema/src/plugins/enhancer/policy/utils.ts (1)
522-522
: LGTM! Consider adding documentation.The implementation correctly uses the new functions to support both data models and type definitions as auth models.
Consider adding a code comment explaining that
getDataModelAndTypeDefs
now supports both models and types for auth declarations, to help future maintainers understand this enhancement.+ // Get auth declaration from either data models or type definitions const authModel = getAuthDecl(getDataModelAndTypeDefs(model.$container, true));
packages/schema/src/plugins/enhancer/enhance/index.ts (1)
89-89
: Consider a more type-safe approach for the default auth type.The current implementation falls back to a generic
AuthUser
type whenauthDecl
is undefined. This might mask type errors at compile time. Consider one of these alternatives:
- Make the auth type parameter required when no auth declaration is present
- Use a more restrictive default type
-const authTypeParam = authDecl ? `auth.${authDecl.name}` : 'AuthUser'; +const authTypeParam = authDecl ? `auth.${authDecl.name}` : 'Record<string, never>';packages/language/src/zmodel.langium (2)
184-184
: Address the TODO to UnifyTypeDef
and AbstractDataModel
The TODO comment indicates an intention to unify
TypeDef
and abstractDataModel
. Would you like assistance in implementing this unification, or should we open a GitHub issue to track this task?
252-252
: Address the TODO: Rename Since It's for BothDataModel
andTypeDef
The TODO comment suggests renaming to reflect that the attribute applies to both
DataModel
andTypeDef
. Would you like assistance in proposing a new name, or should we open a GitHub issue to track this task?packages/schema/src/language-server/zmodel-scope.ts (1)
221-225
: RefactorcreateScopeForContainer
to reduce code duplicationBoth branches in
createScopeForContainer
callthis.createScopeForNodes
with different parameters. Consider refactoring to assign the fields first and make a single call tocreateScopeForNodes
to improve readability and maintainability.Here's a suggested refactor:
private createScopeForContainer(node: AstNode | undefined, globalScope: Scope, includeTypeDefScope = false) { + let fields; if (isDataModel(node)) { - return this.createScopeForNodes(getModelFieldsWithBases(node), globalScope); + fields = getModelFieldsWithBases(node); } else if (includeTypeDefScope && isTypeDef(node)) { - return this.createScopeForNodes(node.fields, globalScope); + fields = node.fields; } else { return EMPTY_SCOPE; } + return this.createScopeForNodes(fields, globalScope); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (2)
packages/language/src/generated/ast.ts
is excluded by!**/generated/**
,!**/generated/**
packages/language/src/generated/grammar.ts
is excluded by!**/generated/**
,!**/generated/**
📒 Files selected for processing (21)
packages/language/src/zmodel.langium
(4 hunks)packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma
(0 hunks)packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma
(0 hunks)packages/plugins/trpc/tests/projects/t3-trpc-v11/prisma/schema.prisma
(0 hunks)packages/schema/src/cli/cli-util.ts
(2 hunks)packages/schema/src/language-server/utils.ts
(2 hunks)packages/schema/src/language-server/validator/attribute-application-validator.ts
(1 hunks)packages/schema/src/language-server/validator/schema-validator.ts
(2 hunks)packages/schema/src/language-server/validator/typedef-validator.ts
(1 hunks)packages/schema/src/language-server/zmodel-linker.ts
(7 hunks)packages/schema/src/language-server/zmodel-scope.ts
(5 hunks)packages/schema/src/plugins/enhancer/enhance/auth-type-generator.ts
(4 hunks)packages/schema/src/plugins/enhancer/enhance/index.ts
(2 hunks)packages/schema/src/plugins/enhancer/policy/utils.ts
(2 hunks)packages/schema/src/res/stdlib.zmodel
(3 hunks)packages/schema/src/utils/ast-utils.ts
(2 hunks)packages/schema/tests/schema/validation/attribute-validation.test.ts
(1 hunks)packages/sdk/src/model-meta-generator.ts
(3 hunks)packages/sdk/src/utils.ts
(5 hunks)tests/integration/tests/enhancements/json/validation.test.ts
(2 hunks)tests/integration/tests/enhancements/with-policy/auth.test.ts
(1 hunks)
💤 Files with no reviewable changes (3)
- packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma
- packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma
- packages/plugins/trpc/tests/projects/t3-trpc-v11/prisma/schema.prisma
🔇 Additional comments (41)
packages/schema/src/language-server/utils.ts (2)
3-3
: LGTM: Import additions are well-organized and properly typed.
The new imports support the feature of using types as auth models by providing necessary type guards and definitions.
Also applies to: 5-6
35-36
: Verify consistent usage of the new type guard.
Let's ensure this new utility function is used consistently across the codebase and doesn't introduce breaking changes.
✅ Verification successful
Based on the shell script results, I can now generate the final response:
The new type guard is used correctly and consistently
The verification shows:
isMemberContainer
is used inzmodel-linker.ts
for type-safe array and operand checks- The individual
isDataModel
andisTypeDef
checks are used appropriately across the codebase, with no conflicting patterns - Type resolution logic in
zmodel-linker.ts
integrates well with the new guard
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check usage patterns of isMemberContainer and related type checks
# Test 1: Find direct usage of isMemberContainer
echo "=== Direct usage of isMemberContainer ==="
rg "isMemberContainer\(" --type ts
# Test 2: Find existing patterns that might need to be updated
echo -e "\n=== Existing patterns that might need updating ==="
rg "isDataModel\(|isTypeDef\(" --type ts
# Test 3: Look for potential breaking changes in type resolution
echo -e "\n=== Related type resolution patterns ==="
rg "resolveType|resolveReference" --type ts
Length of output: 11948
packages/schema/src/language-server/validator/typedef-validator.ts (2)
13-13
: LGTM: Logical placement of attribute validation
The new validation call is well-positioned in the validation sequence, occurring after declaration validation but before field validation.
17-19
: Verify auth model attribute validation
Since this PR aims to allow using types as auth models, let's verify that the validation properly handles auth-related attributes.
✅ Verification successful
Let me try a different approach to verify the auth attribute validation.
Let me try one final search to find the attribute application validator implementation and any auth-related validation logic.
Based on the search results, I can now provide a final response:
Attribute validation appears correctly implemented for types
The validation of attributes on TypeDef follows the same pattern as other declarations (DataModel, Enum, etc.) by using the shared validateAttributeApplication
function. The implementation in AttributeApplicationValidator
shows proper validation of attribute declarations and their targets. While we couldn't find specific auth-related attribute definitions in the codebase, the validation infrastructure is in place to handle them correctly when they are added.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for auth-related attribute definitions and their usage with types
echo "Searching for auth attribute definitions..."
ast-grep --pattern 'attribute $$$ @@@supportTypeDef $$$'
echo "Searching for auth attribute usage with types..."
ast-grep --pattern 'type $$$ {
@@@ $$$
}'
Length of output: 308
Script:
#!/bin/bash
# Search for attribute validation logic and auth-related code
echo "Searching for attribute validation implementation..."
rg -A 5 "validateAttributeApplication"
echo "Searching for auth-related attributes in the schema..."
rg -l "@auth|@model" --type-add 'schema:*.{sdl,graphql}' -tschema
echo "Looking for attribute validation tests..."
fd "test|spec" --exec rg -l "validateAttribute|TypeDefValidator"
Length of output: 7802
Script:
#!/bin/bash
# Search for attribute application validator implementation
echo "Searching attribute application validator..."
rg -A 10 "class AttributeApplicationValidator"
echo "Searching for auth-related validation..."
rg -A 5 "@auth|@model" --type typescript
Length of output: 1719
packages/schema/src/language-server/validator/schema-validator.ts (2)
2-2
: LGTM: Import addition aligns with feature objective
The addition of getDataModelAndTypeDefs
import is appropriate for supporting the new capability of using types as auth models.
39-40
: Verify the impact of auth model validation changes
Let's ensure these changes maintain compatibility and are consistently implemented across the codebase.
✅ Verification successful
Based on the shell script results, I can now generate the final response:
Auth model validation changes are consistently implemented
The changes maintain compatibility as:
- The
getDataModelAndTypeDefs
function is used consistently across the codebase for auth model validation - The auth model validation logic (allowing only one
@@auth
model) is implemented identically in both CLI (cli-util.ts
) and language server (schema-validator.ts
) - Test coverage exists specifically for multiple
@@auth
models validation inschema-validation.test.ts
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of getDataModelAndTypeDefs and auth validation
# Check for other usages of getDataModelAndTypeDefs
echo "Checking usage of getDataModelAndTypeDefs:"
rg "getDataModelAndTypeDefs" -A 2
# Check for other auth model validations
echo "Checking other auth model validations:"
rg "@@auth.*model" -A 2
# Check for potential test cases
echo "Checking related test cases:"
fd -e test.ts -e spec.ts | xargs rg "@@auth"
Length of output: 5772
packages/schema/src/plugins/enhancer/enhance/auth-type-generator.ts (3)
8-9
: LGTM: TypeDef import addition
The addition of TypeDef import is consistent with the PR objective of allowing types as auth models.
92-94
: 🛠️ Refactor suggestion
Add type guard and verify getIdFields compatibility
The code assumes getIdFields can handle both DataModel and TypeDef. Two suggestions:
- Add a type guard for better type safety
- Verify getIdFields compatibility with TypeDef
Consider adding a type guard:
- if (model === authDecl.name) {
+ if (model === authDecl.name && (isDataModel(authDecl) || isTypeDef(authDecl))) {
18-18
: Verify type handling across the codebase
The function now accepts both DataModel and TypeDef, which is a significant change. Let's verify that all callers handle this correctly.
Also applies to: 27-27
✅ Verification successful
Let me gather more information about the implementation to ensure the type handling is correct.
Based on the gathered information, I can now generate the final response:
Function signature change is properly handled
The implementation safely handles both DataModel and TypeDef types:
- The only operations performed on
authDecl
are type-agnostic (accessing name and using getIdFields) - The single caller in
enhance/index.ts
correctly passes theauthDecl
parameter - Type checks using
isDataModel
are used appropriately within the function for specific operations
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for calls to generateAuthType to ensure they handle both types correctly
rg -A 3 "generateAuthType\("
# Search for any remaining references to authModel that might need updating
rg "authModel" --type ts
Length of output: 2525
Script:
#!/bin/bash
# Check the implementation of generateAuthType to see how it handles both types
ast-grep --pattern 'function generateAuthType($_) {
$$$
}'
# Check if there are any type-specific operations on authDecl
rg -B 2 -A 5 "authDecl\." packages/schema/src/plugins/enhancer/enhance/auth-type-generator.ts
# Look for isDataModel or similar type checks
rg "isDataModel|isTypeDef" packages/schema/src/plugins/enhancer/enhance/auth-type-generator.ts
Length of output: 1156
tests/integration/tests/enhancements/json/validation.test.ts (2)
1-1
: LGTM: Appropriate test utilities imported
The import statement includes all necessary test utilities required for the test cases.
136-158
: LGTM: Type-level attribute validation is well tested
The tests properly verify the whitelisting of type-level attributes. Let's verify that these are the only attributes being checked.
✅ Verification successful
Based on the search results from our previous attempts, I can now generate a final response:
Type-level attribute validation is correctly implemented
From the codebase analysis, we can see that:
@@auth
is the only type-level attribute that appears in type declarations@@allow
is correctly rejected on type declarations and is only used with models- Other attributes like
@@index
,@@unique
,@@validate
are specifically model-level attributes
The test correctly verifies the only permitted type-level attribute (@@auth
) while rejecting unauthorized ones (@@allow
), which aligns with the codebase's implementation.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for other type-level attributes in the codebase
ast-grep --pattern 'type $_ {
$$$
@@$_
$$$
}'
Length of output: 53
Script:
#!/bin/bash
# Let's try a different approach to find type-level attributes
# First, search for type declarations in test files
rg "type \w+ \{" tests/ -A 5
# Also search for documentation or schema files that might list allowed attributes
fd "schema|doc" --type f --exec rg "@@" {}
Length of output: 17553
Script:
#!/bin/bash
# Let's search for type-level attribute definitions in the source code
rg "type-level|@@auth|@@allow" src/ -B 2 -A 2
# Also search for validation or attribute-related code
fd "validator|attribute" --type f --exec rg "type.*@@" {}
Length of output: 154
packages/schema/src/utils/ast-utils.ts (2)
16-16
: LGTM: Import additions are appropriate.
The new imports isTypeDef
and TypeDef
are necessary for the enhanced type definition support.
Also applies to: 20-20
317-324
: 🛠️ Refactor suggestion
Verify handling of type definitions in transitive imports.
The function correctly handles data models and type definitions from loaded documents. However, there's a potential issue: when fromModel
is provided, the transitive imports only include data models (via getAllDataModelsIncludingImports
), potentially missing type definitions from imported files.
Let's verify if type definitions from imported files are needed:
If type definitions from imports are needed, consider updating the implementation:
const transitiveDataModels = getAllDataModelsIncludingImports(langiumDocuments, model);
+// Get type definitions from transitive imports
+const transitiveTypeDefs = resolveTransitiveImports(langiumDocuments, model)
+ .flatMap((m) => m.declarations.filter(isTypeDef));
transitiveDataModels.forEach((dm) => {
if (!allDataModels.includes(dm)) {
allDataModels.push(dm);
}
});
+transitiveTypeDefs.forEach((td) => {
+ if (!allDataModels.includes(td)) {
+ allDataModels.push(td);
+ }
+});
packages/schema/src/language-server/validator/attribute-application-validator.ts (1)
72-74
: LGTM! The type declaration validation looks good.
The added validation ensures that only attributes marked with @@@supportTypeDef
can be applied to type declarations, which aligns with the PR objective of allowing types as auth models.
Let's verify the attributes that support type declarations:
✅ Verification successful
The validation for type declarations with @@@supportTypeDef
is correctly implemented.
The search results confirm that:
-
The
@@@supportTypeDef
attribute is properly defined in the standard library (packages/schema/src/res/stdlib.zmodel
) and is used by several attributes including:@id
,@default
- Core Prisma attributes@@auth
- Authentication attribute- All validation attributes (
@length
,@email
,@gt
, etc.)
-
The validation is correctly implemented in
attribute-application-validator.ts
to ensure only attributes marked with@@@supportTypeDef
can be used on type declarations. -
Integration tests demonstrate proper validation of attributes on type declarations, particularly in:
tests/integration/tests/plugins/zod.test.ts
tests/integration/tests/enhancements/with-policy/auth.test.ts
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Find attributes marked with @@@supportTypeDef to ensure proper usage.
# Test: Search for attributes with @@@supportTypeDef. Expect: List of attributes that can be applied to type declarations.
# Search for attribute declarations with @@@supportTypeDef
ast-grep --pattern 'attribute $name {
$$$
@@@supportTypeDef
$$$
}'
# Search for attribute applications on type declarations to ensure they have @@@supportTypeDef
rg -A 5 'type\s+\w+\s*{[\s\n]*@'
Length of output: 228
Script:
#!/bin/bash
# Let's try a different approach to find attributes with @@@supportTypeDef
# and type declarations with attributes
# Search for @@@supportTypeDef in the codebase
rg "@@@supportTypeDef"
# Search for type declarations with attributes using a more reliable pattern
rg "type\s+\w+.*\{" -A 5
# Search for attribute declarations
rg "attribute\s+\w+.*\{"
Length of output: 79035
packages/schema/src/cli/cli-util.ts (1)
2-2
: LGTM: Import updated to support type definitions.
The import change from getDataModels
to getDataModelAndTypeDefs
aligns with the PR's objective of allowing types to be used as auth models.
packages/sdk/src/model-meta-generator.ts (3)
29-29
: LGTM: Import renamed to reflect enhanced functionality.
The import rename from getAuthModel
to getAuthDecl
better reflects its enhanced capability to handle both data models and type definitions as auth models.
104-104
: LGTM: Updated function call with type definitions.
The writeAuthModel
call now correctly includes type definitions, enabling the auth model to be either a data model or a type definition.
165-166
: LGTM: Enhanced auth model handling.
The implementation elegantly combines both data models and type definitions using the spread operator, allowing either to serve as the auth model. This aligns well with the PR objective of allowing types to be used as auth models.
Let's verify that the auth model can be properly resolved from both data models and type definitions:
✅ Verification successful
Based on the shell script results, I can now generate the final response:
Verified: Auth model resolution works correctly for both data models and type definitions
The implementation is correctly handling auth models from both data models and type definitions as evidenced by:
- The
getAuthDecl
function is consistently used across the codebase to resolve auth models from combined data models and type definitions - Schema validation properly enforces single
@@auth
declaration constraint across both types - The stdlib.zmodel confirms
@@auth
attribute supports type definitions with@@@supportTypeDef
- Multiple test cases demonstrate successful auth resolution in both scenarios
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify auth model resolution from both data models and type definitions
# Test: Search for auth-related attributes in both data models and type definitions
rg -A 5 '@auth|@@auth'
# Test: Search for auth model usage in the codebase
ast-grep --pattern 'getAuthDecl($$$)'
Length of output: 11476
packages/sdk/src/utils.ts (1)
134-134
: LGTM! Type definitions properly updated.
The parameter types have been correctly extended to include TypeDef, maintaining consistency with the new feature while preserving existing functionality.
Also applies to: 141-150
packages/schema/src/res/stdlib.zmodel (3)
212-212
: LGTM! Enhanced @id attribute to support type definitions
This is a valuable enhancement that allows type definitions to have ID fields, which is essential for using types as auth models. The attribute parameters remain appropriate for this extended use case.
539-539
: LGTM! Core change enabling type definitions as auth models
This change is central to the PR's objective of allowing types to be used as auth models. However, let's verify the security implications of this enhancement.
✅ Verification successful
Type definition validation for @@auth attribute is properly implemented
The search results show that the codebase has proper validation logic in packages/schema/src/language-server/validator/attribute-application-validator.ts
that checks whether attributes can be applied to type definitions. The validator explicitly checks for the @@@supportTypeDef
marker before allowing attributes on type declarations, which ensures that only explicitly marked attributes (like @@auth) can be used with type definitions. This validation happens at compile-time, preventing any security issues from invalid attribute usage.
Additionally, the presence of auth-related tests in tests/integration/tests/enhancements/with-policy/auth.test.ts
indicates test coverage for both runtime and compile-time auth behavior.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that type definitions with @@auth are properly validated
# and that there are corresponding security checks in the codebase.
# Test 1: Look for validation logic related to auth types
echo "Checking for auth type validation logic..."
rg -l "type.*@@auth|@@auth.*type" --type ts
# Test 2: Look for security-related checks for auth types
echo "Checking for security checks..."
rg -l "validateAuthType|checkAuthType|isValidAuthType" --type ts
# Test 3: Look for potential test coverage
echo "Checking for test coverage..."
rg -l "test.*auth.*type|describe.*auth.*type" --type ts
Length of output: 407
Script:
#!/bin/bash
# Let's try a different approach to find security validations and tests
# Look for auth-related validation code
echo "Searching for auth validation logic..."
rg -A 5 "validateAuth|checkAuth|isValidAuth" --type ts
# Look for auth-related tests
echo "Searching for auth tests..."
rg -A 5 "describe.*auth|test.*auth" --type ts
# Look for type definition handling in auth context
echo "Searching for type definition handling..."
rg -A 5 "supportTypeDef|handleTypeDef|validateTypeDef" --type ts
# Look for auth attribute handling
echo "Searching for auth attribute processing..."
ast-grep --pattern 'function $_($$_) {
$$$
auth
$$$
}'
Length of output: 4240
642-642
: LGTM! Extended validation support to type definitions
The addition of validation support for type definitions is a logical enhancement that complements the auth model changes. Let's verify the validation behavior.
packages/schema/src/plugins/enhancer/enhance/index.ts (2)
6-7
: LGTM: Import changes align with the new auth model approach.
The new imports getAuthDecl
and getDataModelAndTypeDefs
support the transition from model-only to type-inclusive auth declarations.
87-88
: LGTM: Auth declaration changes support type-based auth models.
The transition from authModel
to authDecl
successfully enables using both models and types as auth declarations.
packages/language/src/zmodel.langium (5)
69-69
: Addition of TypeDefField
to ReferenceTarget
Enhances Flexibility
Including TypeDefField
in ReferenceTarget
allows references to type definition fields, enhancing the expressiveness and flexibility of the language.
97-97
: Extending MemberAccessTarget
with TypeDefField
Adding TypeDefField
to MemberAccessTarget
enables member access expressions to utilize type definition fields, which is consistent with the intended language enhancements.
102-102
: Updating MemberAccessExpr
to Include TypeDefField
The grammar correctly updates the MemberAccessExpr
to include TypeDefField
in member access, aligning with the changes made to MemberAccessTarget
.
108-110
: Reinstating Operator Precedence Comments Improves Clarity
Including comments about binary operator precedence enhances the grammar's readability and helps maintainers understand the precedence rules.
188-189
: Allowing Attributes in TypeDef
Definitions
Including attributes+=DataModelAttribute
in TypeDef
allows type definitions to have attributes, enhancing consistency with DataModel
and providing greater flexibility in defining types.
packages/schema/src/language-server/zmodel-scope.ts (2)
139-141
: Verify the correctness of allowTypeDefScope
logic
The variable allowTypeDefScope
is introduced to conditionally include type definitions in the scope when the access starts with auth()
. Please ensure that isAuthOrAuthMemberAccess
accurately identifies all necessary cases where type definitions should be included, and that type definitions are not unintentionally exposed in other contexts.
233-240
: Confirm getAuthDecl
handles combined declarations correctly
In createScopeForAuth
, you're retrieving both data models and type definitions using getAllLoadedAndReachableDataModelsAndTypeDefs
and passing them to getAuthDecl
. Please verify that getAuthDecl
correctly processes this combined list and retrieves the appropriate authentication declaration without unintended side effects.
packages/schema/src/language-server/zmodel-linker.ts (6)
27-27
: Import of TypeDefFieldType
Is Appropriate
The addition of TypeDefFieldType
in the imports ensures that type definitions are correctly handled in the type resolution logic.
39-39
: Addition of Essential Imports for Authentication Resolution
The imported functions getAuthDecl
, getModelFieldsWithBases
, isAuthInvocation
, and isFutureExpr
from @zenstackhq/sdk
are necessary for the updated authentication handling and type resolution.
57-58
: New Utility Imports Support Expanded Functionality
The imports of getAllLoadedAndReachableDataModelsAndTypeDefs
, getContainingDataModel
, and isMemberContainer
are appropriate and support the inclusion of type definitions in data model resolution and member access.
286-293
: Ensuring Accurate Retrieval of Auth Declarations Including Type Definitions
The use of getAllLoadedAndReachableDataModelsAndTypeDefs
to retrieve all declarations, including type definitions, before calling getAuthDecl(allDecls)
is appropriate. This update allows authentication declarations to consider type definitions, enhancing the flexibility of the auth model.
324-324
: Proper Use of isMemberContainer
in Member Access Resolution
The condition now checks isMemberContainer(operandResolved.decl)
to determine if the operand can contain members, correctly encompassing both DataModel
and TypeDef
elements.
342-342
: Adjusting Collection Predicate Resolution with isMemberContainer
By using isMemberContainer(resolvedType.decl)
in the condition, the code accurately identifies when a resolved type is an array of member containers, ensuring correct handling of collection predicates for both data models and type definitions.
tests/integration/tests/enhancements/with-policy/auth.test.ts (3)
910-921
: Comprehensive test coverage of authorization scenarios
The added test cases effectively cover various scenarios, including:
- Attempting to create
Foo
without user context. - Creating with a banned user.
- Creating with an underage user.
- Successful creation with valid user data.
- Attempting to delete without proper permissions.
- Successful deletion with appropriate roles and permissions.
This comprehensive coverage ensures that the authorization logic behaves as expected.
871-885
: Verify the use of @id
annotation on type
definitions
In the schema, User
is defined as a type
, and the field myId
is annotated with @id
. Typically, the @id
attribute is used on model
fields to designate primary keys. Please verify that using @id
on a type
field is supported and behaves as intended.
You can run the following script to search for other occurrences of @id
annotations on type
definitions in the codebase:
890-892
: Ensure the policy conditions correctly handle nested properties
The authorization rules use nested properties of the auth()
object, such as auth().profile.age
and auth().roles?['DELETE' in permissions]
. Since User
is defined as a type
, please confirm that the policy engine correctly resolves these nested properties within type definitions.
Please run the following script to check if nested properties in auth()
are properly supported:
✅ Verification successful
Based on the search results, I can now generate a final response:
Nested properties in auth() policies are properly supported
The codebase shows extensive usage and testing of nested properties in auth() policies:
- Multiple test files validate the functionality of nested auth properties like
auth().profile.age
andauth().roles
- The policy engine implementation in
packages/schema/src/plugins/enhancer/policy/
handles these nested property accesses - Integration tests in
tests/integration/tests/enhancements/with-policy/
specifically verify these scenarios
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that the policy engine supports nested properties in 'auth()' when using type definitions.
# Expected: The policy engine should correctly handle nested properties without errors.
# Search for policy rules using nested 'auth()' properties.
rg -A 2 "auth\(\).*\.profile\.age" packages/language/src/*
Length of output: 166
Script:
#!/bin/bash
# Let's search for auth-related type definitions and policy handling
ast-grep --pattern 'type User {
$$$
}'
# Also search for auth-related policy implementations
rg -l "auth\(\)" --type ts
# Check for any policy engine implementations
rg -l "PolicyEngine|PolicyHandler" --type ts
# Look for auth property resolution or validation logic
rg "\.profile\.|\.roles\?" --type ts
Length of output: 18855
packages/schema/tests/schema/validation/attribute-validation.test.ts (1)
1154-1154
: Test correctly validates unresolved reference error
The test ensures that accessing auth().email
triggers the expected error message when the email
field does not exist on the auth()
object, verifying the validator's ability to catch unresolved member access.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
packages/schema/src/language-server/zmodel-linker.ts (1)
325-325
: Consider adding documentation for isMemberContainer usage.The replacement of
isDataModel
withisMemberContainer
makes the code more generic and extensible to support both data models and type definitions. However, it would be helpful to document this change.Consider adding a comment explaining the member container concept and its implications for type resolution:
if (operandResolved && !operandResolved.array && isMemberContainer(operandResolved.decl)) { + // isMemberContainer checks if the declaration can contain resolvable members + // This includes both data models and type definitionsAlso applies to: 343-343
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
packages/schema/src/language-server/zmodel-linker.ts
(7 hunks)tests/regression/tests/issue-756.test.ts
(1 hunks)
🔇 Additional comments (2)
tests/regression/tests/issue-756.test.ts (1)
31-31
: LGTM! Error message update aligns with the new type system.
The updated error message reflects the architectural improvement where member access targets can now be either DataModelField or TypeDefField, making the error handling more generic and consistent with the new feature of using types as auth models.
Let's verify the consistency of similar error messages:
✅ Verification successful
Error message is consistent with similar reference resolution errors in the codebase
The error message format "Could not resolve reference to X named 'Y'" is consistently used across the codebase for various unresolved references:
- MemberAccessTarget (in issue-756.test.ts and attribute-validation.test.ts)
- ReferenceTarget (in issue-925.test.ts and json/validation.test.ts)
- TypeDeclaration (in datamodel-validation.test.ts)
- FunctionDecl (in attribute-validation.test.ts)
- MemberAccessMember (in json/validation.test.ts)
The grammar definition in packages/language/src/zmodel.langium
confirms that MemberAccessTarget
is a union type of DataModelField | TypeDefField
, making the error message accurate and aligned with the type system.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for similar error message patterns across the codebase
# to ensure consistency in error reporting
# Search for similar error message patterns
rg "Could not resolve reference to \w+ named" -A 2 -B 2
# Search for other MemberAccessTarget related error messages
rg "MemberAccessTarget" -A 2 -B 2
Length of output: 10746
packages/schema/src/language-server/zmodel-linker.ts (1)
287-294
: Verify auth model resolution changes across the codebase.
The changes to auth model resolution now support both data models and type definitions. Let's verify the usage to ensure consistency.
✅ Verification successful
Auth model resolution changes have been properly implemented
The verification shows that:
- No references to the old
getAuthModel
function exist in the codebase - All usages of
getAuthDecl
are consistent across the codebase, properly handling both data models and type definitions - The new
getAllLoadedAndReachableDataModelsAndTypeDefs
function is correctly used in conjunction with auth declaration resolution - The changes are properly integrated in all relevant parts: language server, SDK, and plugins
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for any remaining references to old auth model functions
# and verify the new auth declaration usage.
echo "Checking for old auth model references..."
rg "getAuthModel|getAllLoadedAndReachableDataModels(?!AndTypeDefs)" -l
echo "Verifying auth declaration usage patterns..."
rg "getAuthDecl.*getAllLoadedAndReachableDataModelsAndTypeDefs" -A 3
Length of output: 648
Script:
#!/bin/bash
# Let's break down the search into simpler patterns
echo "Checking for old auth model references..."
rg "getAuthModel" -l
echo "Checking for getAllLoadedAndReachableDataModels without AndTypeDefs..."
rg "getAllLoadedAndReachableDataModels[^A]" -l
echo "Checking current usage of auth declarations..."
rg "getAuthDecl" -A 2
echo "Checking current usage of data models and type defs loading..."
rg "getAllLoadedAndReachableDataModelsAndTypeDefs" -A 2
Length of output: 5320
No description provided.