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

feat: allow using a type as auth model #1841

Merged
merged 3 commits into from
Nov 10, 2024
Merged

feat: allow using a type as auth model #1841

merged 3 commits into from
Nov 10, 2024

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Nov 9, 2024

No description provided.

Copy link
Contributor

coderabbitai bot commented Nov 9, 2024

📝 Walkthrough

Walkthrough

This pull request introduces various modifications to the grammar definitions and validation mechanisms within the ZModel language specification. Key changes include updates to the ReferenceTarget and MemberAccessExpr types, allowing for more complex relationships between data models and type definitions. Additionally, several schema files have undergone comment removals, enhancing clarity without altering functionality. New validation rules and utility functions have been added to improve type resolution and member access handling. Overall, these changes refine the language's expressiveness and validation processes while ensuring clarity and maintainability.

Changes

File Change Summary
packages/language/src/zmodel.langium Updated ReferenceTarget to include TypeDefField, modified MemberAccessExpr to use MemberAccessTarget, and adjusted TypeDef to allow DataModelAttribute fields.
packages/plugins/trpc/tests/projects/nuxt-trpc-v10/prisma/schema.prisma Removed comments and annotations related to the User and Post models.
packages/plugins/trpc/tests/projects/nuxt-trpc-v11/prisma/schema.prisma Removed comments and annotations from the User and Post models.
packages/plugins/trpc/tests/projects/t3-trpc-v11/prisma/schema.prisma Removed @@allow('all', true) annotations from User and Post models.
packages/schema/src/cli/cli-util.ts Changed import from getDataModels to getDataModelAndTypeDefs affecting the validationAfterImportMerge function.
packages/schema/src/language-server/utils.ts Added isMemberContainer function to check if a node can contain resolvable members.
packages/schema/src/language-server/validator/attribute-application-validator.ts Added validation for attributes applied to type definitions requiring @@@supportTypeDef.
packages/schema/src/language-server/validator/schema-validator.ts Updated logic in validate method to use getDataModelAndTypeDefs.
packages/schema/src/language-server/validator/typedef-validator.ts Introduced validateAttributes method for validating attributes of TypeDef.
packages/schema/src/language-server/zmodel-linker.ts Enhanced type resolution and reference linking, updated method signatures.
packages/schema/src/language-server/zmodel-scope.ts Modified scope resolution logic to include type definitions.
packages/schema/src/plugins/enhancer/enhance/auth-type-generator.ts Updated generateAuthType to accept `DataModel
packages/schema/src/plugins/enhancer/enhance/index.ts Replaced getAuthModel with getAuthDecl and introduced getDataModelAndTypeDefs.
packages/schema/src/plugins/enhancer/policy/utils.ts Renamed functions for retrieving models to align with new signatures.
packages/schema/src/res/stdlib.zmodel Added @@supportTypeDef to various attributes for broader applicability.
packages/schema/src/utils/ast-utils.ts Renamed functions to include type definitions in their retrieval logic.
packages/schema/tests/schema/validation/attribute-validation.test.ts Added tests for various attribute validation scenarios.
packages/sdk/src/model-meta-generator.ts Renamed getAuthModel to getAuthDecl and updated its parameters.
packages/sdk/src/utils.ts Added getDataModelAndTypeDefs function and updated related functions to handle type definitions.
tests/integration/tests/enhancements/json/validation.test.ts Introduced new tests for policy rules and member accesses.
tests/integration/tests/enhancements/with-policy/auth.test.ts Added test case for authorization logic using a custom User type.

Possibly related PRs


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 81991fb and d3d49e4.

📒 Files selected for processing (1)
  • tests/integration/tests/enhancements/json/validation.test.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/integration/tests/enhancements/json/validation.test.ts

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?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 validation

While 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 clarity

The 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:

  1. The error message could be more precise to reflect that either a type or model can have @@auth
  2. The boolean parameter in getDataModelAndTypeDefs(model, true) could be more explicit

Consider 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 validation

The 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 access

While the test correctly verifies that valid auth member access works, consider adding test cases for:

  1. Invalid auth member paths
  2. Nested invalid members
  3. 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 validation

The tests effectively cover both normal and authenticated collection access scenarios. However, consider adding test cases for:

  1. Nested collection access (e.g., auth().profile.roles?[org.name == 'X'])
  2. Invalid filter conditions
  3. Type mismatches in filter expressions

Line range hint 1-158: Consider adding tests for edge cases

The test suite is well-structured and covers the main functionality. Consider adding tests for:

  1. Deeply nested type structures
  2. Circular type references
  3. Mixed usage of primitive and complex types
  4. 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 when authDecl is undefined. This might mask type errors at compile time. Consider one of these alternatives:

  1. Make the auth type parameter required when no auth declaration is present
  2. 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 Unify TypeDef and Abstract DataModel

The TODO comment indicates an intention to unify TypeDef and abstract DataModel. 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 Both DataModel and TypeDef

The TODO comment suggests renaming to reflect that the attribute applies to both DataModel and TypeDef. 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: Refactor createScopeForContainer to reduce code duplication

Both branches in createScopeForContainer call this.createScopeForNodes with different parameters. Consider refactoring to assign the fields first and make a single call to createScopeForNodes 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

📥 Commits

Reviewing files that changed from the base of the PR and between ef27d85 and ff004e0.

⛔ 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 in zmodel-linker.ts for type-safe array and operand checks
  • The individual isDataModel and isTypeDef 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 in schema-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:

  1. Add a type guard for better type safety
  2. 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 the authDecl 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:

  1. 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.)
  2. The validation is correctly implemented in attribute-application-validator.ts to ensure only attributes marked with @@@supportTypeDef can be used on type declarations.

  3. 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 and auth().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.

Copy link
Contributor

@coderabbitai coderabbitai bot left a 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 with isMemberContainer 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 definitions

Also applies to: 343-343

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ff004e0 and 81991fb.

📒 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

@ymc9 ymc9 merged commit e59d940 into dev Nov 10, 2024
13 checks passed
@ymc9 ymc9 deleted the chore/type-def-auth branch November 10, 2024 00:28
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.

1 participant