diff --git a/db/migrations/1587079722249-TrueRenamedReviewBody.ts b/db/migrations/1587079722249-TrueRenamedReviewBody.ts new file mode 100644 index 0000000..6593565 --- /dev/null +++ b/db/migrations/1587079722249-TrueRenamedReviewBody.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class TrueRenamedReviewBody1587079722249 implements MigrationInterface { + name = 'TrueRenamedReviewBody1587079722249' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "reviews" RENAME COLUMN "review_text" TO "body"`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "reviews" RENAME COLUMN "body" TO "review_text"`, undefined); + } + +} diff --git a/generated/binding.ts b/generated/binding.ts index 273ffa0..d97c86d 100644 --- a/generated/binding.ts +++ b/generated/binding.ts @@ -76,13 +76,7 @@ export type CollectionItemOrderByInput = 'createdAt_ASC' | 'itemDetailsId_ASC' | 'itemDetailsId_DESC' | 'plays_ASC' | - 'plays_DESC' | - 'artist_ASC' | - 'artist_DESC' | - 'title_ASC' | - 'title_DESC' | - 'mbid_ASC' | - 'mbid_DESC' + 'plays_DESC' export type ItemOrderByInput = 'createdAt_ASC' | 'createdAt_DESC' | @@ -115,8 +109,8 @@ export type ReviewOrderByInput = 'createdAt_ASC' | 'rating_DESC' | 'title_ASC' | 'title_DESC' | - 'reviewText_ASC' | - 'reviewText_DESC' + 'body_ASC' | + 'body_DESC' export type UserOrderByInput = 'createdAt_ASC' | 'createdAt_DESC' | @@ -161,9 +155,6 @@ export interface CollectionItemCreateInput { userId: ID_Output itemDetailsId: ID_Output plays?: Float | null - artist: String - title: String - mbid?: String | null } export interface CollectionItemUpdateInput { @@ -172,9 +163,6 @@ export interface CollectionItemUpdateInput { userId?: ID_Input | null itemDetailsId?: ID_Input | null plays?: Float | null - artist?: String | null - title?: String | null - mbid?: String | null } export interface CollectionItemWhereInput { @@ -222,21 +210,6 @@ export interface CollectionItemWhereInput { plays_lt?: Int | null plays_lte?: Int | null plays_in?: Int[] | Int | null - artist_eq?: String | null - artist_contains?: String | null - artist_startsWith?: String | null - artist_endsWith?: String | null - artist_in?: String[] | String | null - title_eq?: String | null - title_contains?: String | null - title_startsWith?: String | null - title_endsWith?: String | null - title_in?: String[] | String | null - mbid_eq?: String | null - mbid_contains?: String | null - mbid_startsWith?: String | null - mbid_endsWith?: String | null - mbid_in?: String[] | String | null } export interface CollectionItemWhereUniqueInput { @@ -327,14 +300,14 @@ export interface ReviewCreateInput { collectionItemId: ID_Output rating?: String | null title?: String | null - reviewText?: String | null + body?: String | null } export interface ReviewUpdateInput { collectionItemId?: ID_Input | null rating?: String | null title?: String | null - reviewText?: String | null + body?: String | null } export interface ReviewWhereInput { @@ -374,11 +347,11 @@ export interface ReviewWhereInput { title_startsWith?: String | null title_endsWith?: String | null title_in?: String[] | String | null - reviewText_eq?: String | null - reviewText_contains?: String | null - reviewText_startsWith?: String | null - reviewText_endsWith?: String | null - reviewText_in?: String[] | String | null + body_eq?: String | null + body_contains?: String | null + body_startsWith?: String | null + body_endsWith?: String | null + body_in?: String[] | String | null } export interface ReviewWhereUniqueInput { @@ -502,10 +475,10 @@ export interface CollectionItem extends BaseGraphQLObject { itemDetails?: Item | null itemDetailsId: String plays?: Int | null + reviews?: Array | null artist: String title: String - mbid?: String | null - reviews?: Array | null + mbid: String } export interface Item extends BaseGraphQLObject { @@ -547,7 +520,7 @@ export interface Review extends BaseGraphQLObject { collectionItemId: String rating?: String | null title?: String | null - reviewText?: String | null + body?: String | null } export interface StandardDeleteResponse { diff --git a/generated/classes.ts b/generated/classes.ts index 27d0b95..81ee53c 100644 --- a/generated/classes.ts +++ b/generated/classes.ts @@ -532,8 +532,8 @@ export enum ReviewOrderByEnum { title_ASC = "title_ASC", title_DESC = "title_DESC", - reviewText_ASC = "reviewText_ASC", - reviewText_DESC = "reviewText_DESC" + body_ASC = "body_ASC", + body_DESC = "body_DESC" } registerEnumType(ReviewOrderByEnum, { @@ -651,19 +651,19 @@ export class ReviewWhereInput { title_in?: string[]; @TypeGraphQLField({ nullable: true }) - reviewText_eq?: string; + body_eq?: string; @TypeGraphQLField({ nullable: true }) - reviewText_contains?: string; + body_contains?: string; @TypeGraphQLField({ nullable: true }) - reviewText_startsWith?: string; + body_startsWith?: string; @TypeGraphQLField({ nullable: true }) - reviewText_endsWith?: string; + body_endsWith?: string; @TypeGraphQLField(() => [String], { nullable: true }) - reviewText_in?: string[]; + body_in?: string[]; } @TypeGraphQLInputType() @@ -684,7 +684,7 @@ export class ReviewCreateInput { title?: string; @TypeGraphQLField({ nullable: true }) - reviewText?: string; + body?: string; } @TypeGraphQLInputType() @@ -699,7 +699,7 @@ export class ReviewUpdateInput { title?: string; @TypeGraphQLField({ nullable: true }) - reviewText?: string; + body?: string; } @ArgsType() @@ -746,16 +746,7 @@ export enum CollectionItemOrderByEnum { itemDetailsId_DESC = "itemDetailsId_DESC", plays_ASC = "plays_ASC", - plays_DESC = "plays_DESC", - - artist_ASC = "artist_ASC", - artist_DESC = "artist_DESC", - - title_ASC = "title_ASC", - title_DESC = "title_DESC", - - mbid_ASC = "mbid_ASC", - mbid_DESC = "mbid_DESC" + plays_DESC = "plays_DESC" } registerEnumType(CollectionItemOrderByEnum, { @@ -895,51 +886,6 @@ export class CollectionItemWhereInput { @TypeGraphQLField(() => [Int], { nullable: true }) plays_in?: number[]; - - @TypeGraphQLField({ nullable: true }) - artist_eq?: string; - - @TypeGraphQLField({ nullable: true }) - artist_contains?: string; - - @TypeGraphQLField({ nullable: true }) - artist_startsWith?: string; - - @TypeGraphQLField({ nullable: true }) - artist_endsWith?: string; - - @TypeGraphQLField(() => [String], { nullable: true }) - artist_in?: string[]; - - @TypeGraphQLField({ nullable: true }) - title_eq?: string; - - @TypeGraphQLField({ nullable: true }) - title_contains?: string; - - @TypeGraphQLField({ nullable: true }) - title_startsWith?: string; - - @TypeGraphQLField({ nullable: true }) - title_endsWith?: string; - - @TypeGraphQLField(() => [String], { nullable: true }) - title_in?: string[]; - - @TypeGraphQLField({ nullable: true }) - mbid_eq?: string; - - @TypeGraphQLField({ nullable: true }) - mbid_contains?: string; - - @TypeGraphQLField({ nullable: true }) - mbid_startsWith?: string; - - @TypeGraphQLField({ nullable: true }) - mbid_endsWith?: string; - - @TypeGraphQLField(() => [String], { nullable: true }) - mbid_in?: string[]; } @TypeGraphQLInputType() @@ -964,15 +910,6 @@ export class CollectionItemCreateInput { @TypeGraphQLField({ nullable: true }) plays?: number; - - @TypeGraphQLField() - artist!: string; - - @TypeGraphQLField() - title!: string; - - @TypeGraphQLField({ nullable: true }) - mbid?: string; } @TypeGraphQLInputType() @@ -991,15 +928,6 @@ export class CollectionItemUpdateInput { @TypeGraphQLField({ nullable: true }) plays?: number; - - @TypeGraphQLField({ nullable: true }) - artist?: string; - - @TypeGraphQLField({ nullable: true }) - title?: string; - - @TypeGraphQLField({ nullable: true }) - mbid?: string; } @ArgsType() diff --git a/generated/schema.graphql b/generated/schema.graphql index 8220d31..12abb8a 100644 --- a/generated/schema.graphql +++ b/generated/schema.graphql @@ -71,10 +71,10 @@ type CollectionItem implements BaseGraphQLObject { itemDetails: Item itemDetailsId: String! plays: Int + reviews: [Review!] artist: String! title: String! - mbid: String - reviews: [Review!] + mbid: String! } input CollectionItemCreateInput { @@ -83,9 +83,6 @@ input CollectionItemCreateInput { userId: ID! itemDetailsId: ID! plays: Float - artist: String! - title: String! - mbid: String } enum CollectionItemOrderByInput { @@ -105,12 +102,6 @@ enum CollectionItemOrderByInput { itemDetailsId_DESC plays_ASC plays_DESC - artist_ASC - artist_DESC - title_ASC - title_DESC - mbid_ASC - mbid_DESC } input CollectionItemUpdateInput { @@ -119,9 +110,6 @@ input CollectionItemUpdateInput { userId: ID itemDetailsId: ID plays: Float - artist: String - title: String - mbid: String } input CollectionItemWhereInput { @@ -169,21 +157,6 @@ input CollectionItemWhereInput { plays_lt: Int plays_lte: Int plays_in: [Int!] - artist_eq: String - artist_contains: String - artist_startsWith: String - artist_endsWith: String - artist_in: [String!] - title_eq: String - title_contains: String - title_startsWith: String - title_endsWith: String - title_in: [String!] - mbid_eq: String - mbid_contains: String - mbid_startsWith: String - mbid_endsWith: String - mbid_in: [String!] } input CollectionItemWhereUniqueInput { @@ -374,14 +347,14 @@ type Review implements BaseGraphQLObject { collectionItemId: String! rating: String title: String - reviewText: String + body: String } input ReviewCreateInput { collectionItemId: ID! rating: String title: String - reviewText: String + body: String } enum ReviewOrderByInput { @@ -397,15 +370,15 @@ enum ReviewOrderByInput { rating_DESC title_ASC title_DESC - reviewText_ASC - reviewText_DESC + body_ASC + body_DESC } input ReviewUpdateInput { collectionItemId: ID rating: String title: String - reviewText: String + body: String } input ReviewWhereInput { @@ -445,11 +418,11 @@ input ReviewWhereInput { title_startsWith: String title_endsWith: String title_in: [String!] - reviewText_eq: String - reviewText_contains: String - reviewText_startsWith: String - reviewText_endsWith: String - reviewText_in: [String!] + body_eq: String + body_contains: String + body_startsWith: String + body_endsWith: String + body_in: [String!] } input ReviewWhereUniqueInput { diff --git a/src/modules/collection-item/collection-item.model.ts b/src/modules/collection-item/collection-item.model.ts index 61a65ba..2899d16 100644 --- a/src/modules/collection-item/collection-item.model.ts +++ b/src/modules/collection-item/collection-item.model.ts @@ -26,15 +26,21 @@ export class CollectionItem extends BaseModel { @IntField({ nullable: true, default: 0 }) plays?: number - @StringField({ apiOnly: true }) - get artist(): string { - return this.itemDetails.artist; - } + // needs to be nullable for writes + // FIXME: This is calling the database even though apiOnly is true + // (Only occurs for mutation collectionItems, not collectionItem) + // TODO: The other problem seems to be that this.itemDetails doesn't exist by the time the resolver responds + // @StringField({ apiOnly: true, nullable: true }) + // get artist(): string { + // return this.itemDetails.artist; + // } - @StringField({ apiOnly: true }) - get title(): string { - return this.itemDetails.title; - } + // these fields are not required for the field resolvers to work + // however they may be required to make fields nullable + // @StringField({ apiOnly: true, nullable: true }) + // get title(): string { + // return this.itemDetails.title; + // } @StringField({ apiOnly: true, nullable: true }) get mbid(): string | undefined { @@ -47,7 +53,7 @@ export class CollectionItem extends BaseModel { ) reviews?: Review[]; - // FIXME: warthog codegen fails because of optional chaining + // FIXME: warthog codegen fails when using optional chaining // @StringField({ apiOnly: true, nullable: true }) // get rating(): string | undefined { // return this.reviews?.pop()?.rating; // TODO: Do we need the second question mark? diff --git a/src/modules/collection-item/collection-item.resolver.ts b/src/modules/collection-item/collection-item.resolver.ts index d5b67f0..dab3357 100644 --- a/src/modules/collection-item/collection-item.resolver.ts +++ b/src/modules/collection-item/collection-item.resolver.ts @@ -25,7 +25,8 @@ export class CollectionItemResolver { @Args() { where, orderBy, limit, offset }: CollectionItemWhereArgs, @Fields() fields: string[] ): Promise { - return this.service.find(where, orderBy, limit, offset, fields); + // TODO: Be able to use fields here without breaking artist/title fieldResolvers + return this.service.find(where, orderBy, limit, offset); } @Query(() => CollectionItem) @@ -35,11 +36,63 @@ export class CollectionItemResolver { return this.service.findOne(where); } + @FieldResolver(() => String) + async artist(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { + let itemDetails = await ctx.dataLoader.loaders.CollectionItem.itemDetails.load(collectionItem); + return itemDetails.artist; + } + + @FieldResolver(() => String) + async title(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { + let itemDetails = await ctx.dataLoader.loaders.CollectionItem.itemDetails.load(collectionItem); + return itemDetails.title; + } + + // TODO: "Cannot return null for non-nullable field CollectionItem.mbid." + // @FieldResolver(() => String) + // async mbid(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { + // let itemDetails = await ctx.dataLoader.loaders.CollectionItem.itemDetails.load(collectionItem); + // if(itemDetails.mbid) { + // return itemDetails.mbid; + // } + // else { + // return ''; + // } + // } + + @FieldResolver(() => String) + async rating(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { + let reviews = await ctx.dataLoader.loaders.CollectionItem.reviews.load(collectionItem); + if(reviews.length > 0) { + return reviews[reviews.length-1].rating; + } + else { + return ''; + } + } + + @FieldResolver(() => String) + async reviewBody(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { + // TODO: Only loas the most recent review + let reviews = await ctx.dataLoader.loaders.CollectionItem.reviews.load(collectionItem); + if(reviews.length > 0) { + return reviews[reviews.length-1].body; + } + else { + return ''; + } + } + @FieldResolver(() => [Item]) itemDetails(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { return ctx.dataLoader.loaders.CollectionItem.itemDetails.load(collectionItem); } + @FieldResolver(() => [Item]) + reviews(@Root() collectionItem: CollectionItem, @Ctx() ctx: BaseContext): Promise { + return ctx.dataLoader.loaders.CollectionItem.reviews.load(collectionItem); + } + @Mutation(() => CollectionItem) async createCollectionItem( @Arg('data') data: CollectionItemCreateInput, diff --git a/src/modules/collection-item/collection-item.service.ts b/src/modules/collection-item/collection-item.service.ts index b189267..13fce8a 100644 --- a/src/modules/collection-item/collection-item.service.ts +++ b/src/modules/collection-item/collection-item.service.ts @@ -12,4 +12,8 @@ export class CollectionItemService extends BaseService { ) { super(CollectionItem, repository); } + + async getWithItemDetails() { + + } } diff --git a/src/modules/review/review.model.ts b/src/modules/review/review.model.ts index deae3da..77f1df2 100644 --- a/src/modules/review/review.model.ts +++ b/src/modules/review/review.model.ts @@ -16,5 +16,5 @@ export class Review extends BaseModel { title?: string; @StringField({ nullable: true }) - reviewText?: string; + body?: string; } diff --git a/src/modules/user/user.model.ts b/src/modules/user/user.model.ts index 80dea3f..0e7294c 100644 --- a/src/modules/user/user.model.ts +++ b/src/modules/user/user.model.ts @@ -26,5 +26,5 @@ export class User extends BaseModel { () => CollectionItem, (collectionItem: CollectionItem) => collectionItem.user ) - collection?: CollectionItem[]; // TODO: Initialize to empty array + collection?: CollectionItem[]; }