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(zmodel): add new functions currentModel and currentOperation #1925

Merged
merged 2 commits into from
Dec 25, 2024

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Dec 25, 2024

No description provided.

Copy link
Contributor

coderabbitai bot commented Dec 25, 2024

📝 Walkthrough

Walkthrough

This pull request introduces enhancements to the ZModel language server and SDK, focusing on adding two new functions, currentModel and currentOperation, to support more dynamic access policies. The changes include validation logic for these functions, ensuring that their arguments adhere to specified casing options. The implementation spans multiple files, incorporating type definitions, transformation capabilities, and integration tests to validate the new functionality.

Changes

File Change Summary
packages/schema/src/language-server/validator/function-invocation-validator.ts Added validation for currentModel and currentOperation function arguments, ensuring they accept specific casing options.
packages/schema/src/res/stdlib.zmodel Introduced two new functions: currentModel and currentOperation with optional casing parameter.
packages/sdk/src/code-gen.ts Added // @ts-nocheck directive to all source files to bypass TypeScript type checking.
packages/sdk/src/typescript-expression-transformer.ts Added new type Casing, methods for case transformations, and updated function handlers to support context-aware invocations.
tests/integration/tests/enhancements/with-policy/currentModel.test.ts Added comprehensive integration tests for currentModel function with various casing scenarios.
tests/integration/tests/enhancements/with-policy/currentOperation.test.ts Added integration tests for currentOperation function covering different policy and casing scenarios.

Sequence Diagram

sequenceDiagram
    participant Developer
    participant ZModel
    participant Validator
    participant Transformer
    
    Developer->>ZModel: Define policy with currentModel/currentOperation
    ZModel->>Validator: Validate function arguments
    Validator-->>ZModel: Validate casing options
    ZModel->>Transformer: Transform expression
    Transformer->>Transformer: Apply case transformation
    Transformer-->>ZModel: Return transformed value
Loading

Possibly related PRs

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request. We would love to hear your feedback on Discord.


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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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: 2

🧹 Nitpick comments (3)
packages/sdk/src/typescript-expression-transformer.ts (1)

315-326: Potential string-escaping edge case
toStringWithCaseChange handles casing well. However, if the string contains quotes or special characters, inline quoting might produce unexpected results. Consider adding or documenting string sanitization if user input is processed.

packages/sdk/src/code-gen.ts (1)

50-54: Potential hidden type errors
Disabling type checking across all source files hides potential errors. If feasible, consider selectively disabling or addressing specific type errors to maintain type safety.

packages/schema/src/res/stdlib.zmodel (1)

185-193: Document the “expanded” logic for the operation more thoroughly.
The doc comments reference that “all” operations are expanded to multiple operations. If logic is needed to reflect that expansion at runtime (or compile time), clarify how it’s handled or validated.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b41fd93 and 594bb7b.

📒 Files selected for processing (6)
  • packages/schema/src/language-server/validator/function-invocation-validator.ts (1 hunks)
  • packages/schema/src/res/stdlib.zmodel (1 hunks)
  • packages/sdk/src/code-gen.ts (1 hunks)
  • packages/sdk/src/typescript-expression-transformer.ts (10 hunks)
  • tests/integration/tests/enhancements/with-policy/currentModel.test.ts (1 hunks)
  • tests/integration/tests/enhancements/with-policy/currentOperation.test.ts (1 hunks)
🔇 Additional comments (27)
packages/sdk/src/typescript-expression-transformer.ts (6)

23-23: Import usage looks good
The import from langium is necessary for retrieving the containing data model. No concerns here.


44-45: Type definition is concise
Defining Casing as a union of string literals is clear and easy to maintain. Good approach for typed casing options.


156-156: Invocation argument pass-through
Calling handler.value.call(this, expr, args, normalizeUndefined) is consistent. Ensure handlers adapt to the new argument signature as expected.


327-327: No actionable change
This line is just a blank line. No issues here.


328-341: _currentModel
Logic properly retrieves the data model container and applies casing. Ensure all calling sites provide valid usage context since an error is thrown if no containing model is found.


342-360: _currentOperation
Mapping postUpdate to update ensures consistent naming. Good approach for unifying operation context with the new casing options.

tests/integration/tests/enhancements/with-policy/currentOperation.test.ts (9)

1-2: Imports
Imports from @zenstackhq/testtools are correct for loading schemas and errors. No issues here.


3-23: Test: works with specific rules
Thoroughly tests creation policies for User vs. Post. Covers the allow/deny logic well.


25-44: Test: works with all rule
Good demonstration of using @@allow('all', ...). Ensures policies apply consistently across CRUD operations, then verifying create specifically.


46-65: Test: works with upper case
Ensures currentOperation('upper') is recognized as 'CREATE' or 'READ'. Good coverage for uppercase transformations.


67-86: Test: works with lower case
Consistently checks 'create' vs. 'read' in lowercase. Demonstrates the function transformation well.


88-107: Test: works with capitalization
Validates 'Create' vs. 'create'. Ensures partial changes in letter casing are handled properly.


109-128: Test: works with uncapitalization
Similar to the previous test, but ensures the function returns 'create' in certain contexts. Good coverage for 'uncapitalize'.


130-140: Test: complains when used outside policies
Properly checks error handling for disallowed usage in a @default context. This ensures the function is restricted to an access policy scope.


142-153: Test: complains when casing argument is invalid
Confirms that an invalid argument triggers a descriptive error. Solid coverage for input validation.

tests/integration/tests/enhancements/with-policy/currentModel.test.ts (10)

1-2: Imports
No concerns. Standard test scaffolding from @zenstackhq/testtools.


3-24: Test: basic usage
Tests that User creation is allowed and Post creation is rejected. Good basic coverage of currentModel().


26-46: Test: upper case
Proves 'upper' transformation is recognized. Ensures @@allow('create', currentModel('upper') == 'USER').


48-68: Test: lower case
Checks 'lower' transformation. Good coverage for verifying that @@allow('create', currentModel('lower') == 'user') is enforced.


70-90: Test: capitalization
Validates 'capitalize' scenario. Demonstrates how a lowercased model name becomes 'User'.


92-112: Test: uncapitalization
Ensures 'uncapitalize' scenario flips the first character to lowercase. Good coverage for unusual naming styles.


114-134: Test: abstract base inheritance
Checks consistent behavior of currentModel() in child models. Ensures inherited attributes respect the same policy rules.


136-159: Test: delegate base inheritance
Same principle as the abstract base test, validating that currentModel() usage is consistent even when @@delegate is involved.


161-171: Test: complains when used outside policies
Properly verifies error message when currentModel() is used in a @default context.


173-184: Test: complains when casing argument is invalid
Ensures that the validator enforces one of the recognized casing options, rejecting 'foo'.

packages/schema/src/language-server/validator/function-invocation-validator.ts (1)

90-100: Validation for currentModel and currentOperation casing
Checking that the first argument is one of the allowed cases is appropriate. This prevents invalid usage and ensures consistency with the transformer. Consider referencing the same enumeration in the code for stronger consistency.

packages/schema/src/res/stdlib.zmodel (1)

174-181: Clarify the default behavior for the casing parameter.
The documentation indicates that the default is "original", but it's unclear what happens if the parameter is null or any unspecified string. Consider clarifying the fallback behavior or throwing a validation error when casing is invalid.

Would you like me to open a ticket to add parameter validation and default fallback logic within the function body?

packages/schema/src/res/stdlib.zmodel Show resolved Hide resolved
packages/schema/src/res/stdlib.zmodel Show resolved Hide resolved
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

🧹 Nitpick comments (3)
tests/integration/tests/enhancements/with-policy/currentOperation.test.ts (3)

4-23: Consider expanding test coverage for other CRUD operations.

While the test effectively validates the create operation, consider adding test cases for other operations (read, update, delete) to ensure comprehensive coverage.

// Example additional test cases:
await expect(db.user.findMany()).toResolveTruthy();
await expect(db.user.update({ where: { id: 1 }, data: { id: 2 } })).toResolveTruthy();
await expect(db.user.delete({ where: { id: 1 } })).toResolveTruthy();

130-140: Consider testing additional invalid contexts.

While the test validates usage in DefaultValue context, consider adding test cases for other invalid contexts (e.g., @unique, @relation) to ensure comprehensive error handling.

// Example additional test cases:
await expect(loadModelWithError(`
    model User {
        id String @id
        email String @unique(sort: currentOperation())
    }
`)).resolves.toContain('not allowed in the current context: UniqueConstraint');

142-154: Consider testing non-string argument cases.

While the test validates invalid string arguments, consider adding test cases for non-string arguments (e.g., numbers, booleans) to ensure robust type checking.

// Example additional test cases:
await expect(loadModelWithError(`
    model User {
        id String @id
        @@allow('create', currentOperation(123) == 'create')
    }
`)).resolves.toContain('argument must be a string literal');
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 594bb7b and 537836b.

📒 Files selected for processing (1)
  • tests/integration/tests/enhancements/with-policy/currentOperation.test.ts (1 hunks)
🔇 Additional comments (5)
tests/integration/tests/enhancements/with-policy/currentOperation.test.ts (5)

46-86: LGTM! Comprehensive case sensitivity testing.

The test cases effectively cover both upper and lower case transformations with appropriate assertions for both success and failure scenarios.


88-107: LGTM! Well-structured capitalization tests.

The test cases properly validate the capitalization transformation with appropriate positive and negative scenarios.


109-128: LGTM! Thorough uncapitalization tests.

The test cases effectively validate the uncapitalization transformation with proper assertions.


1-154: Overall excellent test coverage with minor enhancement opportunities.

The test suite is well-structured and provides comprehensive coverage of the currentOperation function's features. It effectively validates:

  • Basic functionality with specific rules
  • Integration with 'all' permission rules
  • Various case transformation scenarios
  • Error handling for invalid contexts and arguments

The test organization is clean, and the assertions are meaningful. The suggested enhancements would further strengthen the test suite but are not critical for the current implementation.


25-44: Verify complete coverage of 'all' rule behavior.

The test validates that 'all' rule works with create operation, but it would be valuable to verify that it actually permits all operations when the condition is met.

✅ Verification successful

Let me search for more specific information about the currentOperation() function and its behavior.


Let me search for the implementation details of the 'all' permission rule.


Let me try a different search pattern to find the implementation of permissions.


Based on the test files and implementation, I can now provide a definitive response about the 'all' rule behavior.

Test coverage for 'all' rule is sufficient.

The test correctly validates that the 'all' rule works with the currentOperation() function. Looking at the test context:

  1. The test verifies that when @@allow('all', currentOperation() == 'create') is true:

    • The create operation is allowed (tested by db.user.create() resolving)
    • Other operations are denied when the condition is false (tested by db.post.create() being rejected)
  2. The 'all' permission rule is a shorthand that applies the condition to all operations (create, read, update, delete), which is evident from other test files in the codebase that demonstrate this behavior, particularly in:

    • tests/integration/tests/enhancements/with-policy/toplevel-operations.test.ts
    • tests/integration/tests/enhancements/with-policy/connect-disconnect.test.ts

Therefore, the test provides adequate coverage of the 'all' rule behavior with currentOperation().

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for documentation or implementation of 'all' rule behavior
rg -A 5 "@@allow\('all'" --type ts

Length of output: 67196


Script:

#!/bin/bash
# Search for currentOperation function implementation or tests
rg -A 5 "currentOperation\(\)" --type ts

Length of output: 3528


Script:

#!/bin/bash
# Search for implementation or documentation of 'all' permission
rg -A 10 "permission.*all" --type ts

Length of output: 38


Script:

#!/bin/bash
# Search for permission operations implementation
rg -A 10 "@@allow\('(create|read|update|delete|all)'" --type ts

Length of output: 76272

@ymc9 ymc9 merged commit a0e2b53 into dev Dec 25, 2024
9 checks passed
@ymc9 ymc9 deleted the feat/current-model-current-op branch December 25, 2024 14:59
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