-
-
Save laudaikinhdi/1b781d068753b42a5fe1fd4419bd2286 to your computer and use it in GitHub Desktop.
Revisions
-
tumainimosha revised this gist
Jul 22, 2020 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,4 +1,4 @@ import { paginate } from './paginate'; @Injectable() export class PostService { -
tumainimosha revised this gist
Jul 22, 2020 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -5,8 +5,8 @@ import { PostService } from '../providers/post.service'; export class PostResolver { constructor(private readonly postService: PostService) { } @Query(() => PaginatedPost) getPosts( @Args() pagination: PaginationArgs, @Args() filter: PostFilter, ): Promise<PaginatedPost> { -
tumainimosha created this gist
Jul 22, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ import { ObjectType, Field } from "@nestjs/graphql"; @ObjectType() export class PageInfo { @Field({ nullable: true }) startCursor: string; @Field({ nullable: true }) endCursor: string; @Field() hasPreviousPage: boolean; @Field() hasNextPage: boolean; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,104 @@ import { Logger } from '@nestjs/common'; import { PageInfo } from './page-info'; import { PaginationArgs } from './pagination.args'; import { SelectQueryBuilder, MoreThan, LessThan } from 'typeorm'; /** * Based on https://gist.github.com/VojtaSim/6b03466f1964a6c81a3dbf1f8cec8d5c */ export async function paginate<T>( query: SelectQueryBuilder<T>, paginationArgs: PaginationArgs, cursorColumn = 'id', defaultLimit = 25, ): Promise<any> { const logger = new Logger('Pagination'); // pagination ordering query.orderBy({ [cursorColumn]: 'DESC' }) const totalCountQuery = query.clone(); // FORWARD pagination if (paginationArgs.first) { if (paginationArgs.after) { const offsetId = Number(Buffer.from(paginationArgs.after, 'base64').toString('ascii')); logger.verbose(`Paginate AfterID: ${offsetId}`); query.where({ [cursorColumn]: MoreThan(offsetId) }); } const limit = paginationArgs.first ?? defaultLimit; query.take(limit) } // REVERSE pagination else if (paginationArgs.last && paginationArgs.before) { const offsetId = Number(Buffer.from(paginationArgs.before, 'base64').toString('ascii')); logger.verbose(`Paginate BeforeID: ${offsetId}`); const limit = paginationArgs.last ?? defaultLimit; query .where({ [cursorColumn]: LessThan(offsetId) }) .take(limit); } const result = await query.getMany(); const startCursorId: number = result.length > 0 ? result[0][cursorColumn] : null; const endCursorId: number = result.length > 0 ? result.slice(-1)[0][cursorColumn] : null; const beforeQuery = totalCountQuery.clone(); const afterQuery = beforeQuery.clone(); let countBefore = 0; let countAfter = 0; if (beforeQuery.expressionMap.wheres && beforeQuery.expressionMap.wheres.length) { countBefore = await beforeQuery .andWhere(`${cursorColumn} < :cursor`, { cursor: startCursorId }) .getCount(); countAfter = await afterQuery .andWhere(`${cursorColumn} > :cursor`, { cursor: endCursorId }) .getCount(); } else { countBefore = await beforeQuery .where(`${cursorColumn} < :cursor`, { cursor: startCursorId }) .getCount(); countAfter = await afterQuery .where(`${cursorColumn} > :cursor`, { cursor: endCursorId }) .getCount(); } logger.debug(`CountBefore:${countBefore}`); logger.debug(`CountAfter:${countAfter}`); const edges = result.map((value) => { return { node: value, cursor: Buffer.from(`${value[cursorColumn]}`).toString('base64'), }; }); const pageInfo = new PageInfo(); pageInfo.startCursor = edges.length > 0 ? edges[0].cursor : null; pageInfo.endCursor = edges.length > 0 ? edges.slice(-1)[0].cursor : null; pageInfo.hasNextPage = countAfter > 0; pageInfo.hasPreviousPage = countBefore > 0; // pageInfo.countBefore = countBefore; // pageInfo.countNext = countAfter; // pageInfo.countCurrent = edges.length; // pageInfo.countTotal = countAfter + countBefore + edges.length; return { edges, pageInfo }; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,9 @@ /** * Example of paginated graphql model */ import { Post } from "../models/post.model"; import { ObjectType } from '@nestjs/graphql'; import { Paginated } from "src/shared/pagination/types/paginated"; @ObjectType() export class PaginatedPost extends Paginated(Post) { } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,30 @@ import { Field, ObjectType } from '@nestjs/graphql'; import { Type } from '@nestjs/common'; import { PageInfo } from './page-info'; /** * Based on https://docs.nestjs.com/graphql/resolvers#generics * * @param classRef */ export function Paginated<T>(classRef: Type<T>): any { @ObjectType(`${classRef.name}Edge`, { isAbstract: true }) abstract class EdgeType { @Field(() => String) cursor: string; @Field(() => classRef) node: T; } @ObjectType({ isAbstract: true }) abstract class PaginatedType { @Field(() => [EdgeType], { nullable: true }) edges: EdgeType[]; @Field(() => PageInfo, { nullable: true }) pageInfo: PageInfo; } return PaginatedType; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,18 @@ import { ArgsType, Int, Field } from '@nestjs/graphql'; @ArgsType() export class PaginationArgs { @Field(() => Int, { nullable: true }) first: number; @Field(() => String, { nullable: true }) after: string; @Field(() => Int, { nullable: true }) last: number; @Field(() => String, { nullable: true }) before: string; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,15 @@ import { Post } from "../models/post.model"; import { PostService } from '../providers/post.service'; @Resolver(() => Post) export class PostResolver { constructor(private readonly postService: PostService) { } @Query(() => PaginatedInquiry) getOwnInquiries( @Args() pagination: PaginationArgs, @Args() filter: PostFilter, ): Promise<PaginatedPost> { return this.postService.getPaginatedPosts(pagination, filter); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,23 @@ import { paginate } from 'paginate'; @Injectable() export class PostService { private readonly logger = new Logger('PostService'); constructor( @InjectRepository(PostRepository) private postRepository: PostRepository, ) { } async getPaginatedPosts(paginationArgs: PaginationArgs, filter: PostFilter): Promise<PaginatedPost> { const query = await this.postRepository .createQueryBuilder() .select(); // todo... you can apply filters here to the query as where clauses return paginate(query, paginationArgs); } }