Skip to content
This repository has been archived by the owner on Apr 19, 2023. It is now read-only.

Commit

Permalink
✨ Add pipes for optional int, order by
Browse files Browse the repository at this point in the history
  • Loading branch information
AnandChowdhary committed Oct 22, 2020
1 parent d6beaf8 commit b107497
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 8 deletions.
22 changes: 15 additions & 7 deletions src/modules/user/user.controller.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { Controller, Get } from '@nestjs/common';
import { Controller, Get, Param, ParseIntPipe, Query } from '@nestjs/common';
import { users } from '@prisma/client';
import { OmitSecrets } from 'src/modules/prisma/prisma.interface';
import { OptionalIntPipe } from 'src/pipes/optional-int.pipe';
import { OrderByPipe } from 'src/pipes/order-by.pipe';
import { UsersService } from './user.service';

@Controller('users')
export class UserController {
constructor(private usersService: UsersService) {}

@Get()
async getAll(): Promise<OmitSecrets<users>[]> {
return this.usersService.users({});
async getAll(
@Query('skip', OptionalIntPipe) skip?: number,
@Query('take', OptionalIntPipe) take?: number,
@Query('orderBy', OrderByPipe) orderBy?: Record<string, 'asc' | 'desc'>,
): Promise<OmitSecrets<users>[]> {
return this.usersService.users({ skip, take, orderBy });
}

// @Get('post/:id')
// async getPostById(@Param('id') id: string): Promise<PostModel> {
// return this.postService.post({ id: Number(id) });
// }
@Get(':id')
async get(
@Param('id', ParseIntPipe) id: number,
): Promise<OmitSecrets<users>> {
return this.usersService.user({ id: Number(id) });
}
}
3 changes: 2 additions & 1 deletion src/modules/user/user.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from '@nestjs/common';
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import {
usersUpdateInput,
Expand All @@ -20,6 +20,7 @@ export class UsersService {
const user = await this.prisma.users.findOne({
where: userWhereUniqueInput,
});
if (!user) throw new HttpException('User not found', HttpStatus.NOT_FOUND);
return this.prisma.expose<users>(user);
}

Expand Down
22 changes: 22 additions & 0 deletions src/pipes/optional-int.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import {
PipeTransform,
Injectable,
HttpException,
HttpStatus,
ArgumentMetadata,
} from '@nestjs/common';

/** Convert a string like "1" to a number, but without NaN */
@Injectable()
export class OptionalIntPipe implements PipeTransform {
transform(value: string, metadata: ArgumentMetadata): number | undefined {
if (value == null) return undefined;
const num = Number(value);
if (isNaN(num))
throw new HttpException(
`"${metadata.data}" should be a number, provided "${value}"`,
HttpStatus.UNPROCESSABLE_ENTITY,
);
return num;
}
}
33 changes: 33 additions & 0 deletions src/pipes/order-by.pipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import {
PipeTransform,
Injectable,
HttpException,
HttpStatus,
ArgumentMetadata,
} from '@nestjs/common';

/** Convert a string like "name asc, address desc" to { name: "asc", address: "desc" } */
@Injectable()
export class OrderByPipe implements PipeTransform {
transform(
value: string,
metadata: ArgumentMetadata,
): Record<string, 'asc' | 'desc'> | undefined {
if (value == null) return undefined;
try {
const rules = value.split(',').map(val => val.trim());
const orderBy: Record<string, 'asc' | 'desc'> = {};
rules.forEach(rule => {
const [key, order] = rule.split(' ');
if (!['asc', 'desc'].includes(order)) throw new Error();
rules[key] = order;
});
return orderBy;
} catch (_) {
throw new HttpException(
`"${metadata.data}" should be like "key1 asc, key2 desc", provided "${value}"`,
HttpStatus.UNPROCESSABLE_ENTITY,
);
}
}
}

0 comments on commit b107497

Please sign in to comment.