NestJS module that provides seamless integration between NestJS and Mongoose ODM for MongoDB database operations
80
Pending
Does it follow best practices?
Impact
80%
1.02xAverage score across 10 eval scenarios
Pending
The risk profile of this skill
Factory classes for generating Mongoose schemas and definitions from decorated TypeScript classes. The factory system transforms class-based schema definitions into proper Mongoose schemas with all decorators processed.
Creates complete Mongoose schemas from decorated TypeScript classes.
class SchemaFactory {
/**
* Creates a Mongoose schema from a decorated TypeScript class
* @param target - The decorated class constructor
* @returns Mongoose schema instance
*/
static createForClass<TClass>(target: Type<TClass>): mongoose.Schema<TClass>;
}Usage Examples:
import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
// Define schema class
@Schema()
export class User {
@Prop({ required: true })
name: string;
@Prop({ unique: true })
email: string;
@Prop({ default: Date.now })
createdAt: Date;
}
// Generate Mongoose schema
export const UserSchema = SchemaFactory.createForClass(User);
// Use in module registration
@Module({
imports: [
MongooseModule.forFeature([
{ name: User.name, schema: UserSchema }
])
],
})
export class UserModule {}
// Schema with complex properties
@Schema({
timestamps: true,
collection: 'products'
})
export class Product {
@Prop({ required: true, index: true })
name: string;
@Prop({ required: true, min: 0 })
price: number;
@Prop([String])
tags: string[];
@Prop({
type: {
street: String,
city: String,
country: { type: String, default: 'US' }
}
})
address: {
street: string;
city: string;
country: string;
};
@Virtual()
get displayPrice(): string {
return `$${this.price.toFixed(2)}`;
}
}
export const ProductSchema = SchemaFactory.createForClass(Product);
// Schema with references
@Schema()
export class Order {
@Prop({ type: mongoose.Types.ObjectId, ref: 'User', required: true })
user: mongoose.Types.ObjectId;
@Prop([{
product: { type: mongoose.Types.ObjectId, ref: 'Product', required: true },
quantity: { type: Number, required: true, min: 1 },
price: { type: Number, required: true }
}])
items: {
product: mongoose.Types.ObjectId;
quantity: number;
price: number;
}[];
@Prop({ enum: ['pending', 'processing', 'shipped', 'delivered'] })
status: string;
@Virtual()
get totalAmount(): number {
return this.items.reduce((sum, item) => sum + (item.price * item.quantity), 0);
}
}
export const OrderSchema = SchemaFactory.createForClass(Order);Creates Mongoose schema definitions (plain objects) from decorated classes for advanced schema customization.
class DefinitionsFactory {
/**
* Creates a Mongoose schema definition from a decorated TypeScript class
* @param target - The decorated class constructor
* @returns Mongoose schema definition object
*/
static createForClass(target: Type<unknown>): mongoose.SchemaDefinition;
}Usage Examples:
import { DefinitionsFactory } from '@nestjs/mongoose';
@Schema()
export class BaseDocument {
@Prop({ required: true })
name: string;
@Prop({ default: Date.now })
createdAt: Date;
}
// Get schema definition for customization
const baseDefinition = DefinitionsFactory.createForClass(BaseDocument);
// Create custom schema with definition
const customSchema = new mongoose.Schema({
...baseDefinition,
// Add additional fields
customField: { type: String, default: 'custom-value' },
// Override existing fields
name: { type: String, required: true, uppercase: true },
}, {
timestamps: true,
collection: 'custom_documents'
});
// Use with discriminators
const AnimalSchema = SchemaFactory.createForClass(Animal);
const DogSchema = new mongoose.Schema(DefinitionsFactory.createForClass(Dog));
const CatSchema = new mongoose.Schema(DefinitionsFactory.createForClass(Cat));
AnimalSchema.discriminator('Dog', DogSchema);
AnimalSchema.discriminator('Cat', CatSchema);Processes virtual properties and adds them to existing schemas.
class VirtualsFactory {
/**
* Inspects a class for virtual properties and adds them to a schema
* @param target - The decorated class constructor
* @param schema - The Mongoose schema to add virtuals to
*/
static inspect<TClass>(target: Type<TClass>, schema: mongoose.Schema<TClass>): void;
}Usage Examples:
import { VirtualsFactory } from '@nestjs/mongoose';
@Schema()
export class User {
@Prop({ required: true })
firstName: string;
@Prop({ required: true })
lastName: string;
@Prop()
email: string;
@Virtual()
get fullName(): string {
return `${this.firstName} ${this.lastName}`;
}
@Virtual({
options: {
ref: 'Post',
localField: '_id',
foreignField: 'author'
}
})
posts: any[];
}
// Create schema without virtuals first
const userSchema = new mongoose.Schema({
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: String,
});
// Add virtuals from decorated class
VirtualsFactory.inspect(User, userSchema);
// Schema now includes virtual properties
export const UserSchema = userSchema;import { SchemaFactory, DefinitionsFactory, VirtualsFactory } from '@nestjs/mongoose';
export class CustomSchemaFactory {
static createAdvancedSchema<T>(target: Type<T>, options?: any): mongoose.Schema<T> {
// Get base definition
const definition = DefinitionsFactory.createForClass(target);
// Create schema with custom options
const schema = new mongoose.Schema(definition, {
timestamps: true,
versionKey: false,
...options,
});
// Add virtuals
VirtualsFactory.inspect(target, schema);
// Add custom middleware
schema.pre('save', function() {
if (this.isNew) {
this.createdAt = new Date();
}
});
// Add custom methods
schema.methods.toJSON = function() {
const obj = this.toObject();
delete obj.__v;
return obj;
};
return schema;
}
}
// Usage
@Schema()
export class CustomDocument {
@Prop({ required: true })
title: string;
@Virtual()
get slug(): string {
return this.title.toLowerCase().replace(/\s+/g, '-');
}
}
export const CustomDocumentSchema = CustomSchemaFactory.createAdvancedSchema(
CustomDocument,
{ collection: 'custom_docs' }
);// Base schema components
@Schema()
export class Timestamped {
@Prop({ default: Date.now })
createdAt: Date;
@Prop({ default: Date.now })
updatedAt: Date;
}
@Schema()
export class SoftDeleted {
@Prop({ default: false })
isDeleted: boolean;
@Prop()
deletedAt: Date;
}
// Composed schema
@Schema()
export class BlogPost extends Timestamped {
@Prop({ required: true })
title: string;
@Prop({ required: true })
content: string;
@Prop([String])
tags: string[];
@Virtual()
get excerpt(): string {
return this.content.substring(0, 150) + '...';
}
}
// Create with multiple inheritance patterns
export function createComposedSchema<T>(
target: Type<T>,
mixins: Type<any>[] = []
): mongoose.Schema<T> {
const baseDefinition = DefinitionsFactory.createForClass(target);
// Merge definitions from mixins
const composedDefinition = mixins.reduce((def, mixin) => {
const mixinDef = DefinitionsFactory.createForClass(mixin);
return { ...def, ...mixinDef };
}, baseDefinition);
const schema = new mongoose.Schema(composedDefinition);
// Add virtuals from all classes
[target, ...mixins].forEach(cls => {
VirtualsFactory.inspect(cls, schema);
});
return schema;
}
// Usage
export const BlogPostSchema = createComposedSchema(BlogPost, [Timestamped, SoftDeleted]);Internal functions used by the module system to create NestJS providers.
Creates NestJS providers for synchronous model registration.
/**
* Creates NestJS providers for synchronous models
* @param connectionName - Optional connection name
* @param options - Array of model definitions
* @returns Array of NestJS providers
*/
function createMongooseProviders(
connectionName?: string,
options?: ModelDefinition[]
): Provider[];Creates NestJS providers for asynchronous model registration.
/**
* Creates NestJS providers for asynchronous models
* @param connectionName - Optional connection name
* @param modelFactories - Array of async model factories
* @returns Array of NestJS providers
*/
function createMongooseAsyncProviders(
connectionName?: string,
modelFactories?: AsyncModelFactory[]
): Provider[];Advanced internal system for storing and retrieving decorator metadata.
class TypeMetadataStorage {
/**
* Add property metadata from @Prop decorators
* @param metadata - Property metadata object
*/
addPropertyMetadata(metadata: PropertyMetadata): void;
/**
* Add schema metadata from @Schema decorators
* @param metadata - Schema metadata object
*/
addSchemaMetadata(metadata: SchemaMetadata): void;
/**
* Add virtual metadata from @Virtual decorators
* @param metadata - Virtual metadata object
*/
addVirtualMetadata(metadata: VirtualMetadataInterface): void;
/**
* Get schema metadata for a target class
* @param target - Class constructor
* @returns Schema metadata or undefined
*/
getSchemaMetadataByTarget(target: Type<unknown>): SchemaMetadata | undefined;
/**
* Get virtual metadata for a target class
* @param targetFilter - Class constructor to filter by
* @returns Array of virtual metadata
*/
getVirtualsMetadataByTarget<TClass>(targetFilter: Type<TClass>): VirtualMetadataInterface[];
}docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10