Zync NestJS Data Module
A comprehensive NestJS data module, `zync-nest-data-module` version 1.1.42 provides opinionated solutions for integrating MongoDB with Mongoose into modern web applications. It offers a robust set of features including complete MongoDB/Mongoose integration with structured repositories, transaction management, and schema utilities built around a `BaseSchema` for common document fields. A key differentiator is its automated database backup service, designed to support cloud storage, along with generic base service and repository classes facilitating common CRUD operations and pagination. The module also includes various database helper functions for operations like unique ID generation. Its continuous development, indicated by its version number, suggests an active maintenance cadence. This package aims to streamline data persistence layers in NestJS projects, focusing specifically on Mongoose.
Common errors
-
Error: Cannot find module 'zync-nest-data-module'
cause The package was attempted to be installed from the public npm registry instead of the private AsyncTech registry.fixInstall using `npm install zync-nest-data-module --registry https://registry.asynctechs.com/` or `pnpm add zync-nest-data-module --registry https://registry.asynctechs.com/`. -
Nest can't resolve dependencies of the [Service/Repository]. Please make sure that the argument at index [X] is available in the [Module] context.
cause A required provider (e.g., a custom repository, `TransactionManager`) or module (e.g., `DatabaseModule`, `MongooseModule`) was not correctly imported or provided in the respective NestJS module.fixEnsure that `DatabaseModule` and `BackupModule` are included in the `imports` array of your application's module. If using custom repositories, ensure they are listed in the `providers` array of the consuming module, and that `MongooseModule.forFeature()` is correctly configured for their schemas. -
MongooseError: The 'uri' parameter to 'openUri()' must be a string, got "undefined"
cause The MongoDB connection URI provided to `MongooseModule.forRoot()` is undefined or null, likely due to a missing environment variable.fixSet the `MONGODB_URI` environment variable (e.g., `mongodb://localhost:27017/mydatabase`) or ensure your NestJS configuration correctly passes the database URI to `MongooseModule.forRoot()`. -
MongooseError: Transaction numbers are only allowed on replica sets. Please make sure that your MongoDB instance is running as a replica set.
cause Attempting to use Mongoose transactions (via `TransactionManager`) with a standalone MongoDB instance, which does not support transactions.fixConfigure your MongoDB server as a replica set. For local development, you can start a single-node replica set. Refer to MongoDB documentation for replica set setup.
Warnings
- gotcha This module is primarily published to a private registry (`https://registry.asynctechs.com/`). Attempting to install directly from the public npm registry (`npm install zync-nest-data-module`) will result in a 'package not found' error.
- gotcha The module relies heavily on `mongoose` and `@nestjs/mongoose` as peer dependencies. Ensure that the versions of these peer dependencies in your project are compatible with the module's requirements, especially when upgrading Mongoose to major versions (e.g., Mongoose 7.x to 8.x).
- gotcha The `BaseSchema` and `AbstractBaseRepository` are designed to support soft deletion (via `isDeleted` property). If not handled correctly in queries or business logic, soft-deleted documents might still appear or be inadvertently processed, leading to data inconsistencies or unexpected behavior.
- gotcha Transaction management through `TransactionManager` requires MongoDB to be running as a replica set, even for local development. Transactions will fail with an error if executed against a standalone MongoDB instance.
Install
-
npm install zync-nest-data-module -
yarn add zync-nest-data-module -
pnpm add zync-nest-data-module
Imports
- DatabaseModule
const { DatabaseModule } = require('zync-nest-data-module');import { DatabaseModule } from 'zync-nest-data-module'; - BackupModule
const BackupModule = require('zync-nest-data-module').BackupModule;import { BackupModule } from 'zync-nest-data-module'; - BaseService
import { BaseService } from 'zync-nest-data-module'; - BaseSchema
import { BaseSchema } from 'zync-nest-data-module'; - AbstractBaseRepository
import { AbstractBaseRepository, IPageParams } from 'zync-nest-data-module'; - TransactionManager
import { TransactionManager } from 'zync-nest-data-module';
Quickstart
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { Schema, Prop, SchemaFactory } from '@nestjs/mongoose';
import { Injectable } from '@nestjs/common';
import { SoftDeleteModel } from 'mongoose-delete';
import {
DatabaseModule,
BackupModule,
BaseSchema,
AbstractBaseRepository,
IPageParams
} from 'zync-nest-data-module';
// 1. Define your Mongoose Schema extending BaseSchema
@Schema({
timestamps: true,
collection: 'my_documents'
})
export class MyDocument extends BaseSchema {
@Prop({ required: true, unique: true })
name: string;
@Prop()
description?: string;
}
export const MyDocumentSchema = SchemaFactory.createForClass(MyDocument);
// 2. Create your custom repository
@Injectable()
export class MyRepository extends AbstractBaseRepository<MyDocument> {
constructor(@MongooseInjectModel(MyDocument.name) model: SoftDeleteModel<MyDocument>) {
super(model);
}
protected buildQuery(query: Partial<MyDocument>): any {
return query;
}
public async mapData(data: any, isCreate: boolean): Promise<MyDocument> {
return data;
}
async findByName(name: string): Promise<MyDocument[]> {
return this.find({ name });
}
}
// 3. Set up your NestJS AppModule
@Module({
imports: [
MongooseModule.forRoot(process.env.MONGODB_URI ?? 'mongodb://localhost/test'),
MongooseModule.forFeature([{ name: MyDocument.name, schema: MyDocumentSchema }]),
DatabaseModule, // Integrates core database utilities
BackupModule, // Integrates database backup service
],
providers: [MyRepository],
exports: [MyRepository]
})
export class AppModule {}
// Note: MongooseInjectModel is a placeholder. In a real app, use @nestjs/mongoose's @InjectModel.
// The code above uses a common alias 'MongooseInjectModel' to avoid direct import conflict for example clarity.