npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@concepta/nestjs-report

v7.0.0-alpha.10

Published

Manage reports for several components using one module.

Downloads

80

Readme

Rockets NestJS Report Manager

Manage reports for several components using one module.

Project

NPM Latest NPM Downloads GH Last Commit GH Contrib NestJS Dep

Table of Contents

  1. Tutorial
  2. How to Guide for Reports
  3. Reference
  4. Explanation

Tutorial

This tutorial will guide you through the steps to implement and use the nestjs-report module in your NestJS project. We will use the user-report module as an example.

Step 1: Install Dependencies

First, you need to install the necessary dependencies. Run the following command:

npm install @concepta/nestjs-report @concepta/nestjs-common @nestjs/swagger axios

Step 2: Create DTOs

Create a Data Transfer Object (DTO) for the report. This will define the structure of the data that will be sent to and from the API.

// dto/user-report.dto.ts
import { ReportCreateDto } from '@concepta/nestjs-report';
import { PickType } from '@nestjs/swagger';
import { Exclude } from 'class-transformer';

@Exclude()
export class UserReportCreateDto extends PickType(ReportCreateDto, [
  'name',
] as const) {}

Step 3: Define Constants

Define any constants that will be used throughout the module. For example, you might have constants for service keys, URLs, etc.

// user-report.constants.ts
export const AWS_KEY_FIXTURE = 'my-aws';
export const REPORT_KEY_USER_REPORT = 'user-report';
export const REPORT_SHORT_DELAY_KEY_FIXTURE = 'my-report-short-delay';
export const DOWNLOAD_URL_FIXTURE = 'https://aws-storage.com/downloaded';
export const UPLOAD_URL_FIXTURE = 'https://aws-storage.com/upload';
export const REPORT_NAME_FIXTURE = 'test.pdf';

Step 4: Create the Report Generator Service

Create a service that implements the ReportGeneratorServiceInterface. This service will handle the generation of reports.

import { FileEntityInterface, FileService } from '@concepta/nestjs-file';
import {
  ReportGeneratorResultInterface,
  ReportGeneratorServiceInterface,
} from '@concepta/nestjs-report';
import { ReportStatusEnum } from '@concepta/nestjs-common';
import { Inject, Injectable } from '@nestjs/common';
import axios from 'axios';
import { promises as fs } from 'fs';
import { ReportEntity } from '../entities/report.entity';
import { REPORT_KEY_USER_REPORT } from './user-report.constants';

@Injectable()
export class UserReportGeneratorService
  implements ReportGeneratorServiceInterface
{
  readonly KEY: string = REPORT_KEY_USER_REPORT;
  readonly generateTimeout: number = 60000;

  constructor(
    @Inject(FileService)
    private readonly fileService: FileService,
  ) {}

  async getDownloadUrl(report: ReportEntity): Promise<string> {
    if (!report?.file?.id) return '';
    const file = await this.fileService.fetch({ id: report.file.id });
    return file.downloadUrl || '';
  }

  async generate(
    report: ReportEntity,
  ): Promise<ReportGeneratorResultInterface> {
    try {
      const file = await this.pushFileMetadata(report);
      const tempFilePath = await this.createTempFile(report);
      await this.uploadFileContent(file.uploadUri, tempFilePath);
      await this.cleanupTempFile(tempFilePath);

      return this.createSuccessResult(report, file);
    } catch (error) {
      console.error('Error generating report:', error);
      return this.createErrorResult(report, error);
    }
  }

  private async pushFileMetadata(
    report: ReportEntity,
  ): Promise<FileEntityInterface> {
    return this.fileService.push({
      fileName: report.name,
      contentType: 'text/plain',
      serviceKey: 'aws-storage',
    });
  }

  private async createTempFile(report: ReportEntity): Promise<string> {
    const tempFilePath = `/tmp/${report.name}.txt`;
    await fs.writeFile(tempFilePath, `User: fake username`);
    return tempFilePath;
  }

  private async uploadFileContent(
    uploadUrl: string,
    filePath: string,
  ): Promise<void> {
    const fileContent = await fs.readFile(filePath);
    await axios.put(uploadUrl, fileContent, {
      headers: { 'Content-Type': 'text/plain' },
    });
  }

  private async cleanupTempFile(filePath: string): Promise<void> {
    await fs.unlink(filePath);
  }

  private createSuccessResult(
    report: ReportEntity,
    file: FileEntityInterface,
  ): ReportGeneratorResultInterface {
    return {
      id: report.id,
      status: ReportStatusEnum.Complete,
      file,
    } as ReportGeneratorResultInterface;
  }

  private createErrorResult(
    report: ReportEntity,
    error: Error,
  ): ReportGeneratorResultInterface {
    return {
      id: report.id,
      status: ReportStatusEnum.Error,
      file: null,
      errorMessage: error.message,
    } as ReportGeneratorResultInterface;
  }
}

Step 5: Create the Controller

Create a controller to handle HTTP requests related to the user reports. This controller will use the ReportService to create and fetch reports.

import { ReportService } from '@concepta/nestjs-report';
import { ReportInterface, ReportStatusEnum } from '@concepta/nestjs-common';
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { ApiResponse, ApiTags } from '@nestjs/swagger';
import { REPORT_KEY_USER_REPORT } from './user-report.constants';
import { UserReportCreateDto } from './dto/user-report.dto';

@Controller('user-report')
@ApiTags('user-report')
export class UserController {
  constructor(private reportService: ReportService) {}

  @Post('')
  @ApiResponse({
    description: 'Create a report and return upload and download url',
  })
  async create(@Body() dto: UserReportCreateDto): Promise<ReportInterface> {
    return this.reportService.generate({
      name: dto.name,
      status: ReportStatusEnum.Processing,
      serviceKey: REPORT_KEY_USER_REPORT,
    });
  }

  @Get(':id')
  @ApiResponse({
    description: 'Get report created',
  })
  async get(@Param('id') id: string): Promise<ReportInterface> {
    return this.reportService.fetch({
      id,
    });
  }
}

Step 6: Register the Module

Finally, register the user-report module in your NestJS application. This step typically involves creating a module file and importing necessary services and controllers.

import { Module } from '@nestjs/common';
import { UserController } from './user-report.controller';
import { UserReportGeneratorService } from './user-report-generator.service';
import { ReportService } from '@concepta/nestjs-report';

@Module({
  controllers: [UserController],
  providers: [UserReportGeneratorService, ReportService],
})
export class UserReportModule {}

Step 7: Setup AppModule

Update your AppModule to include the UserReportModule and configure the ReportModule and FileModule as dependencies.

import { Logger, Module } from '@nestjs/common';
import { ConfigModule, ConfigType } from '@nestjs/config';
import { TypeOrmExtModule } from '@concepta/nestjs-typeorm-ext';
import { FileModule } from '@concepta/nestjs-file';
import { ReportModule } from '@concepta/nestjs-report';
import { awsConfig } from './config/aws.config';
import { AwsModule } from './aws/aws.module';
import { AwsStorageService } from './aws/aws-storage.service';
import { UserReportModule } from './user-report/user-report.module';
import { UserReportGeneratorService } from './user-report/user-report-generator.service';
import { FileEntity } from './entities/file.entity';
import { ReportEntity } from './entities/report.entity';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [awsConfig],
    }),
    TypeOrmExtModule.forRoot({
        type: 'sqlite',
        database: ':memory:',
        synchronize: true,
        entities: [FileEntity, ReportEntity],
      }),
    FileModule.forRootAsync({
      imports: [AwsModule],
      inject: [AwsStorageService],
      useFactory: (awsStorageService: AwsStorageService) => ({
        storageServices: [awsStorageService],
      }),
      entities: {
        file: {
          entity: FileEntity,
        },
      },
    }),
    ReportModule.forRootAsync({
      imports: [UserReportModule],
      inject: [UserReportGeneratorService],
      useFactory: (
        userReportGeneratorService: UserReportGeneratorService,
      ) => ({
        reportGeneratorServices: [userReportGeneratorService],
      }),
      entities: {
        report: {
          entity: ReportEntity,
        },
      },
    }),
  ],
})
export class AppModule {}

Testing User Report Generation with cURL

To test the user report generation functionality using cURL, follow these steps:

  • Create a new user report:

    curl -X POST http://localhost:3000/user-report \
    -H "Content-Type: application/json" \
    -d '{"name": "Test User Report"}'

    This will return a JSON response with the created report details, including its ID and status.

  • Check the status of the report using the ID returned from step 1:

    curl -X GET http://localhost:3000/user-report/{reportId}

    Replace {reportId} with the actual ID returned from step 1.

    This will return the report details, including its current status. The status will initially be "Processing" and should change to "Complete" once the report generation is finished.

  • Keep checking the status periodically until it changes to "Complete". Once complete, the response will include the file information with download URL.

These steps allow you to test the user report generation process from creation to retrieval using cURL commands.

Conclusion

By following these steps, you have successfully integrated the nestjs-report module into your NestJS project. You can now create and fetch reports using the provided endpoints.

Feel free to customize the services and controllers as per your application's requirements. Happy coding!

How to Guide for Reports

1. How to Create a New Report Generator Service

To create a new report generator service, you need to implement the ReportGeneratorServiceInterface. Here's a step-by-step guide:

  • Create a new file for your report generator service (e.g., my-report-generator.service.ts).
  • Import the necessary interfaces and implement the ReportGeneratorServiceInterface.
  • Implement the required method: generate.
  • Define the key for the report generator service.

Here's an example of a custom report generator service:

export class MyReportGeneratorService
  implements ReportGeneratorServiceInterface
{
  constructor() {}

  KEY: string = 'my-report-generator';
  generateTimeout: number = 60000;

  async getDownloadUrl(report: ReportInterface): Promise<string> {
   // logic to get download url for the report
  }

  async generate(
    report: ReportInterface,
  ): Promise<ReportGeneratorResultInterface> {
   // logic to generate report
  }
}

2. How to Integrate a New Storage Service

To integrate a new storage service into the ReportModule, follow these steps:

  1. Import the new storage service module into your AppModule.
  2. Configure the ReportModule with the new storage service.

Here's an example of how to integrate the MyStorageService into the ReportModule:

ReportModule.forRoot({
  reportGeneratorServices: [new MyReportGeneratorService()],
  entities: {
    report: {
      entity: ReportEntityFixture,
    },
  },
}),

3. How to Integrate with Multiple Storage Services

To integrate with multiple storage services, you can pass an array of services to the ReportModule.

ReportModule.forRoot({
  reportGeneratorServices: [
    new MyReportGeneratorService(), 
    new MySecondReportGeneratorService()
  ],
  entities: {
    report: {
      entity: ReportEntityFixture,
    },
  },
}),
// to access MyReportGeneratorService
this.reportService.generate({
  name: dto.name,
  status: ReportStatusEnum.Processing,
  serviceKey: 'my-report-generator',
});
// ... 

Reference

For detailed API documentation, please refer to our API Reference. This comprehensive guide provides in-depth information about all available methods, interfaces, and configurations for the @concepta/nestjs-report package.

Explanation

The @concepta/nestjs-report module offers several significant benefits:

Abstraction and Flexibility

  • Provides high-level abstraction for working with reports
  • Allows easy switching between different report generation services
  • Enables addition of new services without affecting the rest of the application
  • Simplifies implementation of custom report generation services

Seamless Integration with File Module

  • Works harmoniously with @concepta/nestjs-file module
  • Enables efficient handling of report files (storage, retrieval, management)
  • Leverages file module capabilities for cohesive system architecture

Easy Customization and Extensibility

  • Straightforward implementation of custom report generation services
  • Allows integration with various reporting tools or libraries
  • Extensible design accommodates diverse reporting needs

Standardized Report Handling

  • Offers consistent interface for working with reports across services
  • Simplifies development process and improves code maintainability
  • Enhances codebase understandability through standardization

Asynchronous Report Generation

  • Built-in support for handling long-running report creation tasks
  • Improves overall application performance and user experience
  • Efficiently manages resource-intensive reporting processes

Centralized Report Management

  • Promotes better organization of code and separation of concerns
  • Simplifies management, updates, and maintenance of report functionality
  • Centralizes report-related operations for improved code structure

TypeORM Integration

  • Enables easy persistence and retrieval of report metadata
  • Facilitates efficient tracking and management of report statuses
  • Seamlessly integrates with TypeORM for data management

Nestjs Ecosystem Compatibility

  • Designed to work seamlessly with other Nestjs modules
  • Follows Nestjs best practices for consistency and ease of use
  • Ensures smooth integration within the broader Nestjs ecosystem

By offering these features, the @concepta/nestjs-report module significantly simplifies report generation and management in Nestjs applications. It provides a robust, flexible solution for various reporting needs, enhancing developer productivity and application performance.