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

fix(mongoose): fix prehook when insertMany is used to hook method #2959

Merged
merged 1 commit into from
Jan 15, 2025

Conversation

Romakita
Copy link
Collaborator

@Romakita Romakita commented Jan 14, 2025

Summary by CodeRabbit

  • New Features

    • Enhanced type safety for Mongoose decorators and hooks.
    • Introduced more flexible method handling for pre and post hooks.
  • Improvements

    • Updated method signatures to use specific Mongoose method types.
    • Improved callback function flexibility for hooks.
    • Expanded options handling for schema configurations.
  • Bug Fixes

    • Resolved potential argument handling issues in hook implementations.

Copy link

coderabbitai bot commented Jan 14, 2025

Walkthrough

The pull request introduces significant type improvements and refinements to the Mongoose ORM decorators and interfaces. The changes primarily focus on enhancing type safety and flexibility for pre and post hooks in the Mongoose schema definition. A new MongooseMethods type is introduced to restrict and standardize the methods that can be used with hooks, replacing generic string methods. The modifications affect multiple files across the Mongoose ORM package, including decorators, interfaces, and utility functions.

Changes

File Change Summary
packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts - Added MongooseMethod and MongooseMethods types
- Updated MongooseHookOptions to be more flexible
- Modified hook callback types to accept variable arguments
- Updated method types in hook interfaces
packages/orm/mongoose/src/decorators/preHook.ts - Updated function signatures to use MongooseMethods
- Refined decorator argument handling
- Added new overloads for static method support
packages/orm/mongoose/src/decorators/postHook.ts - Updated method signatures to use MongooseMethods
- Maintained existing implementation logic
packages/orm/mongoose/src/utils/schemaOptions.ts - Removed MongooseNextCB type import
- Modified buildPreHook function signature
packages/orm/mongoose/src/decorators/*.spec.ts - Updated test cases to use "save" method instead of "method"

Sequence Diagram

sequenceDiagram
    participant Developer
    participant PreHook/PostHook Decorator
    participant SchemaOptions
    participant MongooseSchema

    Developer->>PreHook/PostHook Decorator: Apply decorator with method
    PreHook/PostHook Decorator->>SchemaOptions: Generate schema options
    SchemaOptions->>MongooseSchema: Configure hook with validated method
    MongooseSchema-->>Developer: Return configured schema
Loading

The sequence diagram illustrates the enhanced process of applying pre and post hooks to Mongoose schemas, highlighting the improved method validation and schema configuration workflow.

Finishing Touches

  • 📝 Generate Docstrings (Beta)

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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • 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.

@Romakita Romakita force-pushed the fix-mongoose-hooks-arguments branch from 21c8c5d to 7e7f415 Compare January 14, 2025 20:04
Copy link

@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: 5

🔭 Outside diff range comments (1)
packages/orm/mongoose/src/decorators/postHook.ts (1)

Line range hint 52-71: Further type safety improvements possible.

The implementation could benefit from stronger typing:

  1. The params spread parameter could be typed more specifically based on the overloads
  2. The args parameter in the returned function could leverage the decorator parameter types

Would you like me to propose a more strongly-typed implementation?

🧰 Tools
🪛 Biome (1.9.4)

[error] 52-52: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 68f358a and 7e7f415.

📒 Files selected for processing (6)
  • packages/orm/mongoose/src/decorators/postHook.spec.ts (2 hunks)
  • packages/orm/mongoose/src/decorators/postHook.ts (2 hunks)
  • packages/orm/mongoose/src/decorators/preHook.spec.ts (4 hunks)
  • packages/orm/mongoose/src/decorators/preHook.ts (2 hunks)
  • packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts (1 hunks)
  • packages/orm/mongoose/src/utils/schemaOptions.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/orm/mongoose/src/decorators/postHook.ts

[error] 52-52: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/orm/mongoose/src/decorators/preHook.ts

[error] 55-55: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: test-third-parties (20.12.2)
  • GitHub Check: test-specs (20.12.2)
  • GitHub Check: test-security (20.12.2)
  • GitHub Check: test-platform (20.12.2)
  • GitHub Check: test-orm (20.12.2)
  • GitHub Check: test-core (20.12.2)
  • GitHub Check: test-graphql (20.12.2)
🔇 Additional comments (4)
packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts (1)

7-27: LGTM! Comprehensive list of Mongoose methods.

The new MongooseMethod type properly enumerates all supported Mongoose operations, including insertMany. This improves type safety by preventing invalid method names.

packages/orm/mongoose/src/decorators/preHook.spec.ts (1)

Line range hint 1-70: Add test coverage for insertMany hook.

While the tests cover the basic hook functionality, they don't specifically test the insertMany scenario that this PR aims to fix.

Add a test case to verify the fix:

it("should handle insertMany hook with multiple documents", () => {
  const fn = vi.fn();
  
  @PreHook("insertMany", fn)
  class Test {}
  
  const options = schemaOptions(Test);
  expect(options.pre[0].method).toBe("insertMany");
  expect(options.pre[0].fn).toBeInstanceOf(Function);
});
packages/orm/mongoose/src/decorators/postHook.spec.ts (1)

Line range hint 1-45: Add test coverage for post-insertMany hook.

Similar to the pre-hook tests, add coverage for the insertMany scenario to ensure complete test coverage of the fix.

Add a test case:

it("should handle post-insertMany hook", () => {
  const fn = vi.fn();
  
  @PostHook("insertMany", fn)
  class Test {}
  
  const options = schemaOptions(Test);
  expect(options.post[0].method).toBe("insertMany");
  expect(options.post[0].fn).toBeInstanceOf(Function);
});
✅ Verification successful

Review comment is correct - insertMany hook test coverage is needed

The verification confirms that:

  • insertMany is a valid mongoose method in the type definition
  • No existing test coverage for insertMany hooks exists
  • The suggested test implementation follows the established patterns
🏁 Scripts executed

The following scripts were executed for the analysis:

Error: No shell scripts found


Script:

#!/bin/bash
# Find MongooseMethod type definition
ast-grep --pattern 'type MongooseMethod = $$$'

# Search for existing insertMany hook tests
rg "insertMany.*hook" -B2 -A2

# Check postHook decorator implementation
ast-grep --pattern 'export function PostHook($$$) {
  $$$
}'

Length of output: 1725


Script:

#!/bin/bash
# Check preHook tests for insertMany coverage
rg "insertMany" packages/orm/mongoose/src/decorators/preHook.spec.ts

Length of output: 68

packages/orm/mongoose/src/decorators/preHook.ts (1)

58-66: Verify that the static method binding works with insertMany.

The PR aims to fix prehook with insertMany. The static method binding implementation looks correct, but we should verify it works specifically with insertMany.

Let's check the usage of insertMany with PreHook in the codebase:

✅ Verification successful

Static method binding implementation is correct for insertMany

The binding mechanism is method-agnostic and correctly implemented using bind(args[0]). While there are no specific tests for insertMany, the implementation will work as it uses the same binding logic that's verified for other mongoose methods.

  • Consider adding specific tests for insertMany to improve test coverage.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for PreHook usage with insertMany
rg -B 2 -A 2 '@PreHook.*insertMany' 

# Search for test cases involving insertMany
rg -B 2 -A 2 'insertMany.*test'

Length of output: 71


Script:

#!/bin/bash
# Search for PreHook decorator usage
rg -l '@PreHook'

# Search for insertMany usage in the codebase
rg -B 2 -A 2 'insertMany'

# Look for test files containing insertMany
fd -e test.ts -e spec.ts -x rg -l 'insertMany' {}

# Find static method declarations that might use insertMany
ast-grep --pattern 'static $_ ($$$) { $$$ insertMany $$$ }'

Length of output: 1034


Script:

#!/bin/bash
# Check PreHook test file content
cat packages/orm/mongoose/src/decorators/preHook.spec.ts

# Look for insertMany examples in documentation
cat docs/tutorials/snippets/mongoose/pre-hook.ts

# Check PreHook implementation
cat packages/orm/mongoose/src/decorators/preHook.ts

Length of output: 4419

packages/orm/mongoose/src/utils/schemaOptions.ts Outdated Show resolved Hide resolved
packages/orm/mongoose/src/decorators/postHook.ts Outdated Show resolved Hide resolved
packages/orm/mongoose/src/decorators/preHook.ts Outdated Show resolved Hide resolved
@Romakita Romakita force-pushed the fix-mongoose-hooks-arguments branch 2 times, most recently from a78ca8f to db4e89d Compare January 15, 2025 07:04
Copy link

@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: 1

♻️ Duplicate comments (3)
packages/orm/mongoose/src/decorators/preHook.ts (1)

67-76: 🧹 Nitpick (assertive)

Consider adding validation for decorator arguments in the class decorator case.

In the else branch, when PreHook is used as a class decorator, the code assumes that decoratorArgs[0] is a function (fn) without validating it. If an incorrect argument is passed, it could lead to runtime errors. Adding validation to check if decoratorArgs[0] is a function would enhance robustness.

Apply this diff to add validation:

} else {
+  if (typeof decoratorArgs[0] !== 'function') {
+    throw new Error('PreHook requires a function as the second argument when used as a class decorator');
+  }
   schemaOptions(args[0], {
     pre: [
       {
         method,
         fn: decoratorArgs[0],
         options: decoratorArgs[1]
       }
     ]
   });
}
packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts (1)

30-31: 🧹 Nitpick (assertive)

Consider adding JSDoc comments for hook callback parameters.

The MongoosePreHookCB and MongoosePostHookCB types now accept variable arguments with ...args: unknown[], increasing flexibility. Documenting the expected arguments for each hook method would improve developer experience and maintainability.

Add JSDoc comments to describe the expected arguments:

/**
 * Pre-hook callback that receives the document and additional method-specific arguments.
 * @param doc - The Mongoose document.
 * @param args - Additional arguments specific to the pre-hook method.
 */
export type MongoosePreHookCB<T = any> = (doc: T | MongooseDocument<T>, ...args: unknown[]) => Promise<void> | void;

/**
 * Post-hook callback that receives the document and additional method-specific arguments.
 * @param doc - The Mongoose document.
 * @param args - Additional arguments specific to the post-hook method.
 */
export type MongoosePostHookCB<T = any> = (doc: T | MongooseDocument<T>, ...args: unknown[]) => Promise<void> | void;
packages/orm/mongoose/src/utils/schemaOptions.ts (1)

42-44: 🧹 Nitpick (assertive)

Consider adding a reference to the Mongoose issue.

While the explicit passing of arguments fixes the hook parameters issue, it would be helpful to add a link to the related Mongoose issue for future reference.

-    // we need to explicitly gives args to avoid a bug with mongoose
+    // Explicitly pass args to avoid Mongoose hook arguments bug
+    // See: https://github.com/Automattic/mongoose/issues/[issue-number]
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7e7f415 and db4e89d.

📒 Files selected for processing (6)
  • packages/orm/mongoose/src/decorators/postHook.spec.ts (2 hunks)
  • packages/orm/mongoose/src/decorators/postHook.ts (2 hunks)
  • packages/orm/mongoose/src/decorators/preHook.spec.ts (4 hunks)
  • packages/orm/mongoose/src/decorators/preHook.ts (2 hunks)
  • packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts (1 hunks)
  • packages/orm/mongoose/src/utils/schemaOptions.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: test-third-parties (20.12.2)
  • GitHub Check: test-specs (20.12.2)
  • GitHub Check: test-security (20.12.2)
  • GitHub Check: test-platform (20.12.2)
  • GitHub Check: test-graphql (20.12.2)
  • GitHub Check: test-core (20.12.2)
  • GitHub Check: test-orm (20.12.2)
  • GitHub Check: lint (20.12.2)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (4)
packages/orm/mongoose/src/decorators/preHook.spec.ts (2)

Line range hint 10-19: Tests updated correctly to reflect method name changes.

The method name in the @PreHook decorator has been updated from "method" to "save", aligning the test with the actual Mongoose lifecycle method. The expected schema options now correctly reflect this change.


Line range hint 35-44: Tests accurately adjusted for the method name update.

The second test case also updates the method name to "save" in the @PreHook decorator, ensuring consistency and correctness in the test suite.

packages/orm/mongoose/src/decorators/postHook.ts (1)

49-52: LGTM! Good type safety improvements.

The changes improve type safety in several ways:

  1. Restricting the method parameter to valid Mongoose hook methods
  2. Making the return type more specific with ClassDecorator | StaticMethodDecorator
packages/orm/mongoose/src/decorators/postHook.spec.ts (1)

11-11: LGTM! Test updated to use valid hook method.

The test has been correctly updated to use a valid Mongoose hook method ("save") instead of the generic "method" string, aligning with the new type restrictions.

Also applies to: 20-20

packages/orm/mongoose/src/utils/schemaOptions.ts Outdated Show resolved Hide resolved
@Romakita Romakita force-pushed the fix-mongoose-hooks-arguments branch from db4e89d to 91fac3e Compare January 15, 2025 07:10
Copy link

@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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between db4e89d and 91fac3e.

📒 Files selected for processing (6)
  • packages/orm/mongoose/src/decorators/postHook.spec.ts (2 hunks)
  • packages/orm/mongoose/src/decorators/postHook.ts (2 hunks)
  • packages/orm/mongoose/src/decorators/preHook.spec.ts (4 hunks)
  • packages/orm/mongoose/src/decorators/preHook.ts (2 hunks)
  • packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts (1 hunks)
  • packages/orm/mongoose/src/utils/schemaOptions.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/orm/mongoose/src/utils/schemaOptions.ts

[error] 43-43: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

⏰ Context from checks skipped due to timeout of 90000ms (9)
  • GitHub Check: test-third-parties (20.12.2)
  • GitHub Check: test-security (20.12.2)
  • GitHub Check: test-graphql (20.12.2)
  • GitHub Check: test-specs (20.12.2)
  • GitHub Check: test-platform (20.12.2)
  • GitHub Check: test-orm (20.12.2)
  • GitHub Check: lint (20.12.2)
  • GitHub Check: test-core (20.12.2)
  • GitHub Check: CodeQL-Build
🔇 Additional comments (8)
packages/orm/mongoose/src/interfaces/MongooseSchemaOptions.ts (1)

30-31: Consider documenting the expected arguments in the hook callbacks.

Since the hook callbacks now use ...args: unknown[], it would be helpful to document the expected arguments for each hook type.

packages/orm/mongoose/src/decorators/preHook.ts (1)

67-76: Consider adding validation for invalid decorator usage.

In the else branch, the function assumes that decoratorArgs[0] is a function. Consider adding validation to ensure that decoratorArgs[0] is indeed a function to prevent runtime errors when the decorator is used incorrectly.

packages/orm/mongoose/src/utils/schemaOptions.ts (2)

43-43: Avoid using 'Function' as a type; specify a more precise function signature.

Using 'Function' as a type reduces type safety and can be a source of bugs. Consider defining the specific function type expected for the next parameter to enhance type safety.

🧰 Tools
🪛 Biome (1.9.4)

[error] 43-43: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)


43-44: Good fix for handling Mongoose hook arguments.

Explicitly passing arg1 and arg2 fixes issues with Mongoose hooks not receiving all parameters, especially important for methods like insertMany. This ensures that hooks receive all necessary context.

🧰 Tools
🪛 Biome (1.9.4)

[error] 43-43: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

packages/orm/mongoose/src/decorators/postHook.ts (2)

3-3: LGTM! Import of MongooseMethods type improves type safety.

The addition of the MongooseMethods type import helps restrict hook methods to valid Mongoose operations.


49-52: Great improvement in type safety!

The changes improve type safety in two ways:

  1. Restricting the method parameter to valid Mongoose methods using MongooseMethods type
  2. Providing a more specific return type ClassDecorator | StaticMethodDecorator instead of Function
packages/orm/mongoose/src/decorators/postHook.spec.ts (1)

11-11: LGTM! Test updated to use valid Mongoose method.

The test case now correctly uses "save" as a valid Mongoose method, aligning with the new type restrictions.

Also applies to: 20-20

packages/orm/mongoose/src/decorators/preHook.spec.ts (1)

10-10: LGTM! Tests updated consistently to use valid Mongoose method.

All test cases now correctly use "save" as a valid Mongoose method, maintaining consistency with the new type restrictions.

Also applies to: 19-19, 35-35, 44-44

@Romakita Romakita merged commit c5b0322 into production Jan 15, 2025
12 checks passed
@Romakita Romakita deleted the fix-mongoose-hooks-arguments branch January 15, 2025 07:16
@Romakita
Copy link
Collaborator Author

🎉 This PR is included in version 8.4.2 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant