Skip to content

Commit

Permalink
Merge pull request #25 from heryfitiavana22/nestjs
Browse files Browse the repository at this point in the history
Nestjs backend
  • Loading branch information
heryTz committed Jul 4, 2024
2 parents 3993b82 + 8c3b46c commit fbdaf65
Show file tree
Hide file tree
Showing 47 changed files with 3,525 additions and 64 deletions.
6 changes: 6 additions & 0 deletions .changeset/old-files-listen.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"rcu-back-core": patch
"rcu-nestjs": major
---

feat nestjs backend
1 change: 1 addition & 0 deletions apps/docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default defineConfig({
{ text: "Overview", link: "/guide/backend-overview" },
{ text: "Express", link: "/guide/backend-express" },
{ text: "Fastify", link: "/guide/backend-fastify" },
{ text: "NestJS", link: "/guide/backend-nestjs" },
{ text: "Symfony", link: "/guide/backend-symfony" },
{ text: "Laravel", link: "/guide/backend-laravel" },
],
Expand Down
176 changes: 176 additions & 0 deletions apps/docs/guide/backend-nestjs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# NestJS

## Installation

Via a package manager:

::: code-group

```bash [npm]
npm install rcu-nestjs
```

```bash [yarn]
yarn add rcu-nestjs
```

```bash [pnpm]
pnpm add rcu-nestjs
```

:::

## Usage

Import the `RCUModule` into your application's root module:

```ts
import { Module } from '@nestjs/common';
import { RCUModule } from 'rcu-nestjs';

@Module({
imports: [RCUModule.forRoot()],
// ...
})
export class AppModule {}
```

`RCUModule.forRoot()` method accepts a configuration object of type [RCUModuleConfig](#RCUModuleConfig) to customize the behavior of the module.

::: details Example RCUModuleConfig

::: code-group

```ts [app.module.ts] {8-14}
/// ...
import { JsonStoreProvider, RCUModule } from 'rcu-nestjs';
import { LoggingService } from './logging.service';
import { OnCompletedService } from './on-completed.service';

@Module({
imports: [
RCUModule.forRoot({
store: new JsonStoreProvider('./tmp/rcu.json'),
tmpDir: './tmp',
outputDir: './tmp',
onCompletedService: OnCompletedService,
providers: [LoggingService, OnCompletedService],
}),
],
/// ...
})
export class AppModule {}
```

```ts [logging.service.ts]
import { Injectable } from '@nestjs/common';

@Injectable()
export class LoggingService {
log(message: string) {
console.log(message);
}
}

```

```ts [on-completed.service.ts]
import { Injectable } from '@nestjs/common';
import { OnCompletedInterface } from 'rcu-nestjs';
import { LoggingService } from './logging.service';

@Injectable()
export class OnCompletedService implements OnCompletedInterface {
constructor(private loggingService: LoggingService) {}

handle = async ({ outputFile, fileId }) => {
this.loggingService.log('File completed: ' + fileId);
};
}
```
:::

## API

### RCUModuleConfig <Badge type="info" text="interface" />

```ts
export type RCUModuleConfig = {
store: StoreProviderInterface;
tmpDir: string;
outputDir: string;
onCompletedService: new (...args: any) => OnCompletedInterface;
providers: Provider[];
imports: (Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference<any>)[];
};
```

#### store

- Type: `StoreProviderInterface`
- Default: `JsonStoreProvider`

The `store` parameter is used to store information about the upload, such as the number of the last uploaded chunk, the total number of chunks, etc. The default store is JSON, but you can implement your own by implementing the [StoreProviderInterface](#storeproviderinterface).

#### tmpDir

- Type: `string`
- Default: `./tmp`

Directory to save all binary chunks.

#### outputDir

- Type: `string`
- Default: `./tmp`

Directory to save the complete file.

#### onCompletedService

- Type: `new (...args: any) => OnCompletedInterface`

This service can be used to perform any additional actions or operations after the upload is completed, such as updating a database record or sending a notification. It implements the [OnCompletedInterface](#oncompletedinterface).

#### providers

- Type: Provider[]
- Default: []

This parameter is used to provide custom providers to the `RCUModule`.

#### imports

- Type: `(Type<any> | DynamicModule | Promise<DynamicModule> | ForwardReference<any>)[]`
- Default: []

This parameter is used to import custom modules into the `RCUModule`.

### OnCompletedInterface <Badge type="info" text="interface" />

```ts
export interface OnCompletedInterface {
handle: (data: { outputFile: string; fileId: string }) => Promise<void>;
}
```

- `outputFile`: Path of the uploaded file.
- `fileId`: The ID of the file used to identify the upload. This is specified from [frontend](/guide/frontend-api#setfileid).

### StoreProviderInterface <Badge type="info" text="interface" />

```ts
export type Upload = {
id: string;
chunkCount: number;
lastUploadedChunkNumber: number;
chunkFilenames: string[];
};

export interface StoreProviderInterface {
getItem(id: string): Promise<Upload | undefined>;
createItem(id: string, chunkCount: number): Promise<Upload>;
updateItem(id: string, update: Partial<Upload>): Promise<Upload>;
removeItem(id: string): Promise<void>;
}
```
1 change: 1 addition & 0 deletions apps/docs/guide/backend-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- [Express](/guide/backend-express)
- [Fastify](/guide/backend-fastify)
- [Symfony](/guide/backend-symfony)
- [NestJS](/guide/backend-nestjs)

## Community

Expand Down
25 changes: 25 additions & 0 deletions examples/nestjs/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
57 changes: 57 additions & 0 deletions examples/nestjs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# compiled output
/dist
/node_modules
/build

# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# OS
.DS_Store

# Tests
/coverage
/.nyc_output

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# temp directory
.temp
.tmp
tmp

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
4 changes: 4 additions & 0 deletions examples/nestjs/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
15 changes: 15 additions & 0 deletions examples/nestjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# NestJS example for Resumable Chunk Upload

This is an example show how to use ```rcu-nestjs```

Install:

```bash
pnpm install
```

Run the server:

```bash
pnpm start:dev
```
8 changes: 8 additions & 0 deletions examples/nestjs/nest-cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}
66 changes: 66 additions & 0 deletions examples/nestjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{
"name": "nestjs",
"version": "1.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix"
},
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"hbs": "^4.2.0",
"rcu-nestjs": "workspace:*",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"prettier": "^3.0.0",
"source-map-support": "^0.5.21",
"supertest": "^7.0.0",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
Loading

0 comments on commit fbdaf65

Please sign in to comment.