npm package: @khoativi/nestjs-upload-file
Description: A powerful, pluggable NestJS module for uploading and managing files using Amazon S3 or compatible storage services. Supports both Express and Fastify platforms.
Author: Khoa Tran
Latest version: 1.0.0

# @khoativi/nestjs-upload-file

`@khoativi/nestjs-upload-file` helps you easily upload, validate, manage, and serve files via S3-compatible storage systems. It also integrates seamlessly with CDN providers, and supports access control via ACL.

## ✨ Key Features

- ⚙️ **Pluggable S3 Storage** — Upload to AWS S3 or any compatible endpoint (MinIO, Wasabi, etc.)
- ⚡ **High-Speed Upload** — Multipart support for large files via `@aws-sdk/lib-storage`
- 🛡️ **Access Control** — Public/private file ACL management
- 🌐 **CDN Integration** — Return CDN URLs for public access
- 🎛️ **MIME & Size Validation** — Configurable restrictions
- 📦 **Framework Agnostic** — Works with both `Express` and `Fastify`
- 🧪 **Fully Tested** — Comes with Jest setup and coverage support

## 📦 Installation

Using **npm**:

```bash
npm install @khoativi/nestjs-upload-file @aws-sdk/client-s3
```

Using **yarn**:

```bash
yarn add @khoativi/nestjs-upload-file @aws-sdk/client-s3
```

Using **pnpm**:

```bash
pnpm add @khoativi/nestjs-upload-file @aws-sdk/client-s3
```

## 🧰 Usage

### Express (default)

```ts
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
```

### Fastify

```ts
// main.ts
import { NestFactory } from '@nestjs/core';
import {
  FastifyAdapter,
  NestFastifyApplication
} from '@nestjs/platform-fastify';
import multipart from '@fastify/multipart';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter()
  );
  await app.register(multipart);
  await app.listen(3000, '0.0.0.0');
}
bootstrap();
```

### Register the Module

```ts
// app.module.ts
import { FileUploadModule } from '@khoativi/nestjs-upload-file';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot(),
    FileUploadModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        storage: 's3',
        bucketName: config.get('AWS_BUCKET_NAME'),
        s3Options: {
          credentials: {
            accessKeyId: config.get('AWS_ACCESS_KEY'),
            secretAccessKey: config.get('AWS_SECRET_KEY')
          },
          region: config.get('AWS_REGION_NAME'),
          endpoint: config.get('AWS_ENDPOINT_URL')
        },
        cdnBaseUrl: config.get('CDN_BASE_URL'),
        allowedMimeTypes: ['image/png', 'image/jpeg'],
        maxFileSize: 5 * 1024 * 1024 // 5MB
      })
    })
  ]
})
export class AppModule {}
```

### Example Controller

```ts
// file-upload.controller.ts
import {
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
  Body
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { FileUploadService, S3ObjectACL } from '@khoativi/nestjs-upload-file';

@Controller('upload')
export class FileUploadController {
  constructor(private readonly uploadService: FileUploadService) {}

  @Post('single')
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(
    @UploadedFile() file: Express.Multer.File,
    @Body('acl') acl: S3ObjectACL
  ) {
    const result = await this.uploadService.uploadFile(file.originalname, {
      buffer: file.buffer,
      acl
    });
    return result;
  }
}
```

## ⚙️ Configuration Options

| Option             | Type             | Required | Description                                                           |
| ------------------ | ---------------- | -------- | --------------------------------------------------------------------- |
| `storage`          | `'s3'`           | ✅       | The storage backend (currently only S3 supported)                     |
| `bucketName`       | `string`         | ✅       | Name of the S3 bucket                                                 |
| `s3Options`        | `S3ClientConfig` | ✅       | Configuration for the S3 client (region, credentials, endpoint, etc.) |
| `cdnBaseUrl`       | `string`         | ⛔       | Optional CDN base URL (e.g. `https://cdn.example.com`)                |
| `allowedMimeTypes` | `string[]`       | ⛔       | List of allowed MIME types                                            |
| `maxFileSize`      | `number`         | ⛔       | Max file size in bytes                                                |

## 🐛 Issues and Contributing

Please [open an issue](https://github.com/khoativi/nestjs-upload-file/issues) if you find a bug or have a feature request. We welcome contributions via pull requests.

## 📄 License

MIT License © [Khoa Trần](https://github.com/khoativi)