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 schema when default value is used on collection #2971

Merged
merged 1 commit into from
Jan 24, 2025

Conversation

Romakita
Copy link
Collaborator

@Romakita Romakita commented Jan 24, 2025

Closes: #2968

Information

Type Breaking change
fix No

Todos

  • Tests
  • Coverage
  • Example
  • Documentation

Summary by CodeRabbit

  • Tests

    • Added new test cases for schema creation to verify:
      • Schemas with collection of subdocuments and default values
      • Schemas with discriminator keys
      • Schemas with version keys
  • Refactor

    • Updated schema type handling and definition structures
    • Modified function signatures to support more flexible type definitions
  • Documentation

    • Improved type support for default values in schema decorators

Copy link

coderabbitai bot commented Jan 24, 2025

Walkthrough

The pull request introduces modifications to the Mongoose ORM schema creation utilities and schema decorators. The changes primarily focus on enhancing the schema creation process, improving type handling, and addressing issues with default values for array properties. The modifications span across multiple files in the packages/orm/mongoose and packages/specs/schema directories, updating import statements, function signatures, and type definitions to provide more flexible and precise schema generation.

Changes

File Change Summary
packages/orm/mongoose/src/utils/createSchema.spec.ts - Added new test cases for schema creation with subdocuments, discriminator keys, and version keys
- Updated expected output structures for various test classes
packages/orm/mongoose/src/utils/createSchema.ts - Updated import statements to include classOf and isClassObject
- Modified createSchemaTypeOptions function signature to return SchemaDefinitionProperty
- Adjusted type handling for schema creation
packages/specs/schema/src/decorators/common/default.ts - Added import for JSONSchema6Type
- Updated Default function parameter type to JSONSchema6Type | undefined
packages/specs/schema/src/domain/JsonSchema.ts - Modified default method signature to accept JSONSchema6Type | undefined

Assessment against linked issues

Objective Addressed Explanation
Override default Mongoose behavior of saving empty arrays
Support setting default value as undefined for array properties
Prevent automatic saving of empty arrays for missing properties Requires further validation in actual implementation

Possibly related PRs

✨ 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.

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 936825b and e31add2.

📒 Files selected for processing (4)
  • packages/orm/mongoose/src/utils/createSchema.spec.ts (6 hunks)
  • packages/orm/mongoose/src/utils/createSchema.ts (4 hunks)
  • packages/specs/schema/src/decorators/common/default.ts (2 hunks)
  • packages/specs/schema/src/domain/JsonSchema.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test-specs (20.12.2)
  • GitHub Check: test-orm (20.12.2)
🔇 Additional comments (15)
packages/orm/mongoose/src/utils/createSchema.ts (7)

1-1: Good import usage for new utilities
This import now includes classOf and isClassObject, which are pivotal for handling enum types and class checks.


5-5: SchemaDefinitionProperty import
Importing SchemaDefinitionProperty allows a more precise return type when creating schema definitions, aligning with Mongoose's standard.


145-145: Signature change to return SchemaDefinitionProperty
Switching from a more generic SchemaTypeOptions<T> variant to SchemaDefinitionProperty strengthens typing fidelity. Ensure all calling sites and external references are updated to match the new signature.


149-149: Required property logic
Using a function for required is a clever approach to dynamically evaluate field requirement. This aligns well with Ts.ED’s advanced use cases.


174-174: Direct enum assignment
Populating enum: jsonSchema["enum"] helps unify the schema definition for enumerated properties. This looks correct.


186-189: Array type definition
Returning an array structure through type: [schemaTypeOptions.type] is the proper Mongoose approach for nested arrays and subdocuments.


197-203: Map of subdocuments
Decomposing defaultValue and required ensures clarity, while of: otherOpts captures subdocument configuration. Confirm that this default logic for Map aligns with intended usage (e.g., returning an empty Map if no default is specified).

packages/orm/mongoose/src/utils/createSchema.spec.ts (6)

468-471: Validating array of subdocuments
The test confirms the schema is constructed with an array of subdocuments, verifying that each element references the childrenSchema.


500-547: Testing default undefined for subdocument array
This comprehensive test ensures that having @Default(undefined) correctly results in an optional array. The logic verifying an array of enum: [String] is also nicely covered.


585-589: Array of refs test
The test accurately verifies an array of references to Children3. The final schema shape matches Mongoose’s standard usage.


679-681: Map of subdocuments test
Validates the Map structure is generated correctly, with each map value referencing childrenSchema. This aligns with the refactored logic in createSchemaTypeOptions.


776-776: Discriminator key test
Confirms the schema properly sets the discriminatorKey from @DiscriminatorKey(). This ensures correct usage of Mongoose’s discriminator feature.


789-789: Version key test
Verifies @VersionKey() is applied and recognized by the schema. Ensures that the version key aligns with user-defined property names.

packages/specs/schema/src/decorators/common/default.ts (2)

1-2: Use typed import from 'json-schema'
Importing JSONSchema6Type as a type-only import is consistent with best practices and aligns with the updated default value requirements.


45-45: 🧹 Nitpick (assertive)

Consider omitting the default property when the value is undefined
If undefined is passed as the default value, it may produce a property "default": undefined in the final JSON Schema, which is not valid JSON. If the intention is to have "no default," you might avoid setting this property altogether.

Below is a suggested approach:

 export function Default(defaultValue: JSONSchema6Type | undefined) {
   return JsonEntityFn((store) => {
-    store.itemSchema.default(defaultValue);
+    if (defaultValue !== undefined) {
+      store.itemSchema.default(defaultValue);
+    }
   });
 }

Additionally, consider verifying occurrences of @Default(...) calls to ensure no incompatible types (like functions) are being passed:

✅ Verification successful

The review comment is correct - undefined defaults should be omitted

The implementation directly stores the undefined value in the schema using Map.set(), which would result in invalid JSON when serialized. The suggested approach to skip setting the default property when the value is undefined is the correct solution, as it:

  • Prevents invalid JSON Schema generation
  • Better represents the semantic meaning of "no default value"
  • Follows JSON Schema best practices
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
rg -A 5 '@Default'

Length of output: 33577


Script:

#!/bin/bash
# Check the Default decorator implementation and related tests
rg -A 10 "export function Default" packages/specs/schema/src/decorators/common/default.ts
rg -A 10 "describe.*Default" packages/specs/schema/src/decorators/common/default.spec.ts

Length of output: 523


Script:

#!/bin/bash
# Check JsonSchema store implementation and schema output tests
rg -A 10 "class JsonSchema" packages/specs/schema/src/domain/JsonSchema.ts
rg -B 5 -A 10 "default.*undefined" packages/specs/schema/src/domain/JsonSchema.ts

Length of output: 1156

@Romakita Romakita merged commit 519d17c into production Jan 24, 2025
12 checks passed
@Romakita Romakita deleted the fix-2968-mongoose-default-value-on-collection branch January 24, 2025 14:02
@Romakita
Copy link
Collaborator Author

🎉 This PR is included in version 8.4.4 🎉

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.

[BUG] Unable to stop saving empty arrays in Mongoose when array not set
1 participant