video.resolver.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. import {
  2. Arg,
  3. Args,
  4. Mutation,
  5. Query,
  6. Root,
  7. Resolver,
  8. FieldResolver,
  9. ObjectType,
  10. Field,
  11. Int,
  12. ArgsType,
  13. } from 'type-graphql';
  14. import { Inject } from 'typedi';
  15. import { Min } from 'class-validator';
  16. import { Fields, StandardDeleteResponse, UserId, PageInfo, RawFields } from 'warthog';
  17. import {
  18. VideoCreateInput,
  19. VideoCreateManyArgs,
  20. VideoUpdateArgs,
  21. VideoWhereArgs,
  22. VideoWhereInput,
  23. VideoWhereUniqueInput,
  24. VideoOrderByEnum,
  25. } from '../../../generated';
  26. import { Video } from './video.model';
  27. import { VideoService } from './video.service';
  28. import { Block } from '../block/block.model';
  29. import { getConnection } from 'typeorm';
  30. @ObjectType()
  31. export class VideoEdge {
  32. @Field(() => Video, { nullable: false })
  33. node!: Video;
  34. @Field(() => String, { nullable: false })
  35. cursor!: string;
  36. }
  37. @ObjectType()
  38. export class VideoConnection {
  39. @Field(() => Int, { nullable: false })
  40. totalCount!: number;
  41. @Field(() => [VideoEdge], { nullable: false })
  42. edges!: VideoEdge[];
  43. @Field(() => PageInfo, { nullable: false })
  44. pageInfo!: PageInfo;
  45. }
  46. @ArgsType()
  47. export class ConnectionPageInputOptions {
  48. @Field(() => Int, { nullable: true })
  49. @Min(0)
  50. first?: number;
  51. @Field(() => String, { nullable: true })
  52. after?: string; // V3: TODO: should we make a RelayCursor scalar?
  53. @Field(() => Int, { nullable: true })
  54. @Min(0)
  55. last?: number;
  56. @Field(() => String, { nullable: true })
  57. before?: string;
  58. }
  59. @ArgsType()
  60. export class VideoConnectionWhereArgs extends ConnectionPageInputOptions {
  61. @Field(() => VideoWhereInput, { nullable: true })
  62. where?: VideoWhereInput;
  63. @Field(() => VideoOrderByEnum, { nullable: true })
  64. orderBy?: VideoOrderByEnum;
  65. }
  66. @Resolver(Video)
  67. export class VideoResolver {
  68. constructor(@Inject('VideoService') public readonly service: VideoService) {}
  69. @Query(() => [Video])
  70. async videos(
  71. @Args() { where, orderBy, limit, offset }: VideoWhereArgs,
  72. @Fields() fields: string[]
  73. ): Promise<Video[]> {
  74. return this.service.find<VideoWhereInput>(where, orderBy, limit, offset, fields);
  75. }
  76. @Query(() => VideoConnection)
  77. async videoConnection(
  78. @Args() { where, orderBy, ...pageOptions }: VideoConnectionWhereArgs,
  79. @RawFields() fields: Record<string, any>
  80. ): Promise<VideoConnection> {
  81. let result: any = {
  82. totalCount: 0,
  83. edges: [],
  84. pageInfo: {
  85. hasNextPage: false,
  86. hasPreviousPage: false,
  87. },
  88. };
  89. // If the related database table does not have any records then an error is thrown to the client
  90. // by warthog
  91. try {
  92. result = await this.service.findConnection<VideoWhereInput>(where, orderBy, pageOptions, fields);
  93. } catch (err) {
  94. console.log(err);
  95. // TODO: should continue to return this on `Error: Items is empty` or throw the error
  96. if (!(err.message as string).includes('Items is empty')) throw err;
  97. }
  98. return result as Promise<VideoConnection>;
  99. }
  100. @FieldResolver(() => Block)
  101. async happenedIn(@Root() r: Video): Promise<Block> {
  102. const result = await getConnection()
  103. .getRepository(Video)
  104. .findOne(r.id, { relations: ['happenedIn'] });
  105. if (!result || !result.happenedIn) {
  106. throw new Error('Unable to find result for Video.happenedIn');
  107. }
  108. return result.happenedIn;
  109. }
  110. }