UNPKG

@sonibble-creators/nest-microservice-pack

Version:
143 lines (123 loc) 3.62 kB
import { Type } from '@nestjs/common'; import { ObjectType, Field } from '@nestjs/graphql'; import Relay from 'graphql-relay'; // type tobe used in pagination // return the actual data const typeMap = {}; /** * ## Paginated * * The pagination of the object graphql * allow to paginated and sort the data * using the cursor, or the offset and limit * * * @param type * @returns */ export function Paginated<T>(type: Type<T>): any { const { name } = type; if (typeMap[`${name}`]) return typeMap[`${name}`]; /** * ### Edge * * The edge object for pagination * will come with cursor, and the node field * will generate and Edge based on the type extends into the params * * This class will never registered into the scheme * */ @ObjectType(`${name}Edge`, { isAbstract: true }) class Edge<T> implements Relay.Edge<T> { public name = `${name}Edge`; @Field({ nullable: true, description: `The cursor for ${name} pagination` }) public cursor!: Relay.ConnectionCursor; @Field(() => type, { nullable: true, description: `Node of the ${name} data`, }) public node!: T; } /** * ### PageInfo * * Page information of the edge * will generate some of info depends on the parameters class extends * * */ @ObjectType(`${name}PageInfo`, { isAbstract: true }) class PageInfo implements Relay.PageInfo { @Field({ nullable: true, description: `The start cursor for ${name}` }) public startCursor!: Relay.ConnectionCursor; @Field({ nullable: true, description: `The end cursor for ${name}` }) public endCursor!: Relay.ConnectionCursor; @Field(() => Boolean, { description: `Whether there are more items to fetch before for ${name}`, }) public hasPreviousPage!: boolean; @Field(() => Boolean, { description: `Whether there is a next page for ${name}`, }) public hasNextPage!: boolean; } /** * ### Connection * * Will generated connection for the type extends * cover some data inside like edges, pageInfo, * * */ @ObjectType(`${name}Connection`, { isAbstract: true }) class Connection implements Relay.Connection<T> { public name = `${name}Connection`; @Field(() => [Edge], { nullable: true, description: `Edges of the ${name} data`, }) public edges!: Edge<T>[]; @Field(() => PageInfo, { nullable: true, description: `Page info of the edges, like the cursor and posibillity to next or prev for ${name} data`, }) public pageInfo!: PageInfo; } /** * ### Page * * The final result will be become when data * become paginated, the actual data will show is page, and pageData */ @ObjectType(`${name}Page`, { isAbstract: true }) abstract class Page { public name = `${name}Page`; @Field(() => Connection, { description: `The ${name} data of the page` }) public page!: Connection; @Field(() => PageData, { nullable: true, description: `The ${name} data information will be showed like count, limit, and the offset`, }) public pageData!: PageData; } typeMap[`${name}`] = Page; return typeMap[`${name}`]; } /** * ### PageData * * Show some info of the pagination * like count of the data, limit and the offset * * */ @ObjectType() export class PageData { @Field({ description: `Data count in the page` }) public count: number; @Field({ description: `Limit data for the page` }) public limit: number; @Field({ description: `The offset data will be showed next and before` }) public offset: number; }