diff --git a/README.md b/README.md index 1d3a2f6..726b419 100644 --- a/README.md +++ b/README.md @@ -1 +1,4 @@ -docker-compose exec -u postgres postgres psql \ No newline at end of file +docker-compose exec -u postgres postgres psql +\l +\c +\dt diff --git a/db/migrations/1584861008595-CreateUserTable.ts b/db/migrations-old/1584861008595-CreateUserTable.ts similarity index 100% rename from db/migrations/1584861008595-CreateUserTable.ts rename to db/migrations-old/1584861008595-CreateUserTable.ts diff --git a/db/migrations-old/1587075769273-True.ts b/db/migrations-old/1587075769273-True.ts new file mode 100644 index 0000000..4ad677a --- /dev/null +++ b/db/migrations-old/1587075769273-True.ts @@ -0,0 +1,26 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class True1587075769273 implements MigrationInterface { + name = 'True1587075769273' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "reviews" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "collection_item_id" character varying NOT NULL, "rating" character varying, "title" character varying, "review_text" character varying, CONSTRAINT "PK_231ae565c273ee700b283f15c1d" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`ALTER TABLE "users" ADD "password" character varying NOT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "users" ADD "salt" character varying NOT NULL`, undefined); + await queryRunner.query(`ALTER TABLE "users" ADD "account_settings" jsonb`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" ADD "plays" integer DEFAULT 0`, undefined); + await queryRunner.query(`ALTER TABLE "users" ADD CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email")`, undefined); + await queryRunner.query(`ALTER TABLE "reviews" ADD CONSTRAINT "FK_fc090d3e6b0a3b369f03d9aa673" FOREIGN KEY ("collection_item_id") REFERENCES "collection_items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "reviews" DROP CONSTRAINT "FK_fc090d3e6b0a3b369f03d9aa673"`, undefined); + await queryRunner.query(`ALTER TABLE "users" DROP CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3"`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" DROP COLUMN "plays"`, undefined); + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "account_settings"`, undefined); + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "salt"`, undefined); + await queryRunner.query(`ALTER TABLE "users" DROP COLUMN "password"`, undefined); + await queryRunner.query(`DROP TABLE "reviews"`, undefined); + } + +} diff --git a/db/migrations/1587076386589-True.ts b/db/migrations/1587076386589-True.ts new file mode 100644 index 0000000..fa0eb4c --- /dev/null +++ b/db/migrations/1587076386589-True.ts @@ -0,0 +1,26 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class True1587076386589 implements MigrationInterface { + name = 'True1587076386589' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "users" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "username" character varying NOT NULL, "email" character varying, "password" character varying NOT NULL, "salt" character varying NOT NULL, "bio" character varying, "account_settings" jsonb, CONSTRAINT "UQ_97672ac88f789774dd47f7c8be3" UNIQUE ("email"), CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE TABLE "items" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "mbid" character varying, "rym_id" integer, "spotify_id" character varying, "title" character varying NOT NULL, "disambiguation" character varying, "artist" character varying NOT NULL, CONSTRAINT "PK_ba5885359424c15ca6b9e79bcf6" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE TABLE "reviews" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "collection_item_id" character varying NOT NULL, "rating" character varying, "title" character varying, "review_text" character varying, CONSTRAINT "PK_231ae565c273ee700b283f15c1d" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`CREATE TABLE "collection_items" ("id" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "created_by_id" character varying NOT NULL, "updated_at" TIMESTAMP DEFAULT now(), "updated_by_id" character varying, "deleted_at" TIMESTAMP, "deleted_by_id" character varying, "version" integer NOT NULL, "custom_title" character varying, "custom_artist" character varying, "user_id" character varying NOT NULL, "item_details_id" character varying NOT NULL, "plays" integer DEFAULT 0, CONSTRAINT "PK_5f299da96958a920ab58871ea57" PRIMARY KEY ("id"))`, undefined); + await queryRunner.query(`ALTER TABLE "reviews" ADD CONSTRAINT "FK_fc090d3e6b0a3b369f03d9aa673" FOREIGN KEY ("collection_item_id") REFERENCES "collection_items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" ADD CONSTRAINT "FK_11904cd0bab7d35969089548db8" FOREIGN KEY ("user_id") REFERENCES "users"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" ADD CONSTRAINT "FK_08f049748e8a0c61e1c7b247028" FOREIGN KEY ("item_details_id") REFERENCES "items"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "collection_items" DROP CONSTRAINT "FK_08f049748e8a0c61e1c7b247028"`, undefined); + await queryRunner.query(`ALTER TABLE "collection_items" DROP CONSTRAINT "FK_11904cd0bab7d35969089548db8"`, undefined); + await queryRunner.query(`ALTER TABLE "reviews" DROP CONSTRAINT "FK_fc090d3e6b0a3b369f03d9aa673"`, undefined); + await queryRunner.query(`DROP TABLE "collection_items"`, undefined); + await queryRunner.query(`DROP TABLE "reviews"`, undefined); + await queryRunner.query(`DROP TABLE "items"`, undefined); + await queryRunner.query(`DROP TABLE "users"`, undefined); + } + +} 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/db/migrations/1587097918918-AddCoverArt.ts b/db/migrations/1587097918918-AddCoverArt.ts new file mode 100644 index 0000000..ded7eaa --- /dev/null +++ b/db/migrations/1587097918918-AddCoverArt.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class AddCoverArt1587097918918 implements MigrationInterface { + name = 'AddCoverArt1587097918918' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "items" ADD "cover_art" character varying`, undefined); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "items" DROP COLUMN "cover_art"`, undefined); + } + +} diff --git a/docker-compose.yml b/docker-compose.yml index 8a6cd18..88d3b01 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '2.4' services: postgres: - image: postgres:11 + image: postgres:12 restart: always volumes: - ./db_data:/var/lib/postgresql/data diff --git a/generated/binding.ts b/generated/binding.ts index 2801edf..cd4fceb 100644 --- a/generated/binding.ts +++ b/generated/binding.ts @@ -1,3 +1,5 @@ +import 'graphql-import-node'; // Needed so you can import *.graphql files + import { makeBindingClass, Options } from 'graphql-binding' import { GraphQLResolveInfo, GraphQLSchema } from 'graphql' import { IResolvers } from 'graphql-tools/dist/Interfaces' @@ -8,6 +10,8 @@ export interface Query { collectionItem: (args: { where: CollectionItemWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , items: >(args: { offset?: Int | null, limit?: Int | null, where?: ItemWhereInput | null, orderBy?: ItemOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , item: (args: { where: ItemWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , + reviews: >(args: { offset?: Int | null, limit?: Int | null, where?: ReviewWhereInput | null, orderBy?: ReviewOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , + review: (args: { where: ReviewWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , users: >(args: { offset?: Int | null, limit?: Int | null, where?: UserWhereInput | null, orderBy?: UserOrderByInput | null }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , user: (args: { where: UserWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise } @@ -21,6 +25,10 @@ export interface Mutation { createManyItems: >(args: { data: Array }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , updateItem: (args: { data: ItemUpdateInput, where: ItemWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , deleteItem: (args: { where: ItemWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , + createReview: (args: { data: ReviewCreateInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , + createManyReviews: >(args: { data: Array }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , + updateReview: (args: { data: ReviewUpdateInput, where: ReviewWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , + deleteReview: (args: { where: ReviewWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , createUser: (args: { data: UserCreateInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , createManyUsers: >(args: { data: Array }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , updateUser: (args: { data: UserUpdateInput, where: UserWhereUniqueInput }, info?: GraphQLResolveInfo | string, options?: Options) => Promise , @@ -47,7 +55,7 @@ export interface BindingConstructor { new(...args: any[]): T } -export const Binding = makeBindingClass>({ schema }) +export const Binding = makeBindingClass>({ schema: schema as any }) /** * Types @@ -66,7 +74,11 @@ export type CollectionItemOrderByInput = 'createdAt_ASC' | 'userId_ASC' | 'userId_DESC' | 'itemDetailsId_ASC' | - 'itemDetailsId_DESC' + 'itemDetailsId_DESC' | + 'plays_ASC' | + 'plays_DESC' | + 'mbid_ASC' | + 'mbid_DESC' export type ItemOrderByInput = 'createdAt_ASC' | 'createdAt_DESC' | @@ -85,7 +97,24 @@ export type ItemOrderByInput = 'createdAt_ASC' | 'disambiguation_ASC' | 'disambiguation_DESC' | 'artist_ASC' | - 'artist_DESC' + 'artist_DESC' | + 'coverArt_ASC' | + 'coverArt_DESC' + +export type ReviewOrderByInput = 'createdAt_ASC' | + 'createdAt_DESC' | + 'updatedAt_ASC' | + 'updatedAt_DESC' | + 'deletedAt_ASC' | + 'deletedAt_DESC' | + 'collectionItemId_ASC' | + 'collectionItemId_DESC' | + 'rating_ASC' | + 'rating_DESC' | + 'title_ASC' | + 'title_DESC' | + 'body_ASC' | + 'body_DESC' export type UserOrderByInput = 'createdAt_ASC' | 'createdAt_DESC' | @@ -129,6 +158,8 @@ export interface CollectionItemCreateInput { customArtist?: String | null userId: ID_Output itemDetailsId: ID_Output + plays?: Float | null + mbid?: String | null } export interface CollectionItemUpdateInput { @@ -136,30 +167,35 @@ export interface CollectionItemUpdateInput { customArtist?: String | null userId?: ID_Input | null itemDetailsId?: ID_Input | null + plays?: Float | null + mbid?: String | null } export interface CollectionItemWhereInput { - id_eq?: String | null - id_in?: String[] | String | null - createdAt_eq?: String | null - createdAt_lt?: String | null - createdAt_lte?: String | null - createdAt_gt?: String | null - createdAt_gte?: String | null - createdById_eq?: String | null - updatedAt_eq?: String | null - updatedAt_lt?: String | null - updatedAt_lte?: String | null - updatedAt_gt?: String | null - updatedAt_gte?: String | null - updatedById_eq?: String | null + id_eq?: ID_Input | null + id_in?: ID_Output[] | ID_Output | null + createdAt_eq?: DateTime | null + createdAt_lt?: DateTime | null + createdAt_lte?: DateTime | null + createdAt_gt?: DateTime | null + createdAt_gte?: DateTime | null + createdById_eq?: ID_Input | null + createdById_in?: ID_Output[] | ID_Output | null + updatedAt_eq?: DateTime | null + updatedAt_lt?: DateTime | null + updatedAt_lte?: DateTime | null + updatedAt_gt?: DateTime | null + updatedAt_gte?: DateTime | null + updatedById_eq?: ID_Input | null + updatedById_in?: ID_Output[] | ID_Output | null deletedAt_all?: Boolean | null - deletedAt_eq?: String | null - deletedAt_lt?: String | null - deletedAt_lte?: String | null - deletedAt_gt?: String | null - deletedAt_gte?: String | null - deletedById_eq?: String | null + deletedAt_eq?: DateTime | null + deletedAt_lt?: DateTime | null + deletedAt_lte?: DateTime | null + deletedAt_gt?: DateTime | null + deletedAt_gte?: DateTime | null + deletedById_eq?: ID_Input | null + deletedById_in?: ID_Output[] | ID_Output | null customTitle_eq?: String | null customTitle_contains?: String | null customTitle_startsWith?: String | null @@ -174,52 +210,68 @@ export interface CollectionItemWhereInput { userId_in?: ID_Output[] | ID_Output | null itemDetailsId_eq?: ID_Input | null itemDetailsId_in?: ID_Output[] | ID_Output | null + plays_eq?: Int | null + plays_gt?: Int | null + plays_gte?: Int | null + plays_lt?: Int | null + plays_lte?: Int | null + plays_in?: Int[] | Int | 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 { - id: String + id: ID_Output } export interface ItemCreateInput { mbid?: String | null rymId?: Float | null - spotifyId?: ID_Input | null - title?: String | null + spotifyId?: String | null + title: String disambiguation?: String | null - artist?: String | null + artist: String + coverArt?: String | null } export interface ItemUpdateInput { mbid?: String | null rymId?: Float | null - spotifyId?: ID_Input | null + spotifyId?: String | null title?: String | null disambiguation?: String | null artist?: String | null + coverArt?: String | null } export interface ItemWhereInput { - id_eq?: String | null - id_in?: String[] | String | null - createdAt_eq?: String | null - createdAt_lt?: String | null - createdAt_lte?: String | null - createdAt_gt?: String | null - createdAt_gte?: String | null - createdById_eq?: String | null - updatedAt_eq?: String | null - updatedAt_lt?: String | null - updatedAt_lte?: String | null - updatedAt_gt?: String | null - updatedAt_gte?: String | null - updatedById_eq?: String | null + id_eq?: ID_Input | null + id_in?: ID_Output[] | ID_Output | null + createdAt_eq?: DateTime | null + createdAt_lt?: DateTime | null + createdAt_lte?: DateTime | null + createdAt_gt?: DateTime | null + createdAt_gte?: DateTime | null + createdById_eq?: ID_Input | null + createdById_in?: ID_Output[] | ID_Output | null + updatedAt_eq?: DateTime | null + updatedAt_lt?: DateTime | null + updatedAt_lte?: DateTime | null + updatedAt_gt?: DateTime | null + updatedAt_gte?: DateTime | null + updatedById_eq?: ID_Input | null + updatedById_in?: ID_Output[] | ID_Output | null deletedAt_all?: Boolean | null - deletedAt_eq?: String | null - deletedAt_lt?: String | null - deletedAt_lte?: String | null - deletedAt_gt?: String | null - deletedAt_gte?: String | null - deletedById_eq?: String | null + deletedAt_eq?: DateTime | null + deletedAt_lt?: DateTime | null + deletedAt_lte?: DateTime | null + deletedAt_gt?: DateTime | null + deletedAt_gte?: DateTime | null + deletedById_eq?: ID_Input | null + deletedById_in?: ID_Output[] | ID_Output | null mbid_eq?: String | null mbid_contains?: String | null mbid_startsWith?: String | null @@ -231,8 +283,11 @@ export interface ItemWhereInput { rymId_lt?: Int | null rymId_lte?: Int | null rymId_in?: Int[] | Int | null - spotifyId_eq?: ID_Input | null - spotifyId_in?: ID_Output[] | ID_Output | null + spotifyId_eq?: String | null + spotifyId_contains?: String | null + spotifyId_startsWith?: String | null + spotifyId_endsWith?: String | null + spotifyId_in?: String[] | String | null title_eq?: String | null title_contains?: String | null title_startsWith?: String | null @@ -248,46 +303,120 @@ export interface ItemWhereInput { artist_startsWith?: String | null artist_endsWith?: String | null artist_in?: String[] | String | null + coverArt_eq?: String | null + coverArt_contains?: String | null + coverArt_startsWith?: String | null + coverArt_endsWith?: String | null + coverArt_in?: String[] | String | null } export interface ItemWhereUniqueInput { - id: String + id: ID_Output +} + +export interface ReviewCreateInput { + collectionItemId: ID_Output + rating?: String | null + title?: String | null + body?: String | null +} + +export interface ReviewUpdateInput { + collectionItemId?: ID_Input | null + rating?: String | null + title?: String | null + body?: String | null +} + +export interface ReviewWhereInput { + id_eq?: ID_Input | null + id_in?: ID_Output[] | ID_Output | null + createdAt_eq?: DateTime | null + createdAt_lt?: DateTime | null + createdAt_lte?: DateTime | null + createdAt_gt?: DateTime | null + createdAt_gte?: DateTime | null + createdById_eq?: ID_Input | null + createdById_in?: ID_Output[] | ID_Output | null + updatedAt_eq?: DateTime | null + updatedAt_lt?: DateTime | null + updatedAt_lte?: DateTime | null + updatedAt_gt?: DateTime | null + updatedAt_gte?: DateTime | null + updatedById_eq?: ID_Input | null + updatedById_in?: ID_Output[] | ID_Output | null + deletedAt_all?: Boolean | null + deletedAt_eq?: DateTime | null + deletedAt_lt?: DateTime | null + deletedAt_lte?: DateTime | null + deletedAt_gt?: DateTime | null + deletedAt_gte?: DateTime | null + deletedById_eq?: ID_Input | null + deletedById_in?: ID_Output[] | ID_Output | null + collectionItemId_eq?: ID_Input | null + collectionItemId_in?: ID_Output[] | ID_Output | null + rating_eq?: String | null + rating_contains?: String | null + rating_startsWith?: String | null + rating_endsWith?: String | null + rating_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 + body_eq?: String | null + body_contains?: String | null + body_startsWith?: String | null + body_endsWith?: String | null + body_in?: String[] | String | null +} + +export interface ReviewWhereUniqueInput { + id: ID_Output } export interface UserCreateInput { username: String email?: String | null + password: String bio?: String | null + accountSettings?: JSONObject | null } export interface UserUpdateInput { username?: String | null email?: String | null + password?: String | null bio?: String | null + accountSettings?: JSONObject | null } export interface UserWhereInput { - id_eq?: String | null - id_in?: String[] | String | null - createdAt_eq?: String | null - createdAt_lt?: String | null - createdAt_lte?: String | null - createdAt_gt?: String | null - createdAt_gte?: String | null - createdById_eq?: String | null - updatedAt_eq?: String | null - updatedAt_lt?: String | null - updatedAt_lte?: String | null - updatedAt_gt?: String | null - updatedAt_gte?: String | null - updatedById_eq?: String | null + id_eq?: ID_Input | null + id_in?: ID_Output[] | ID_Output | null + createdAt_eq?: DateTime | null + createdAt_lt?: DateTime | null + createdAt_lte?: DateTime | null + createdAt_gt?: DateTime | null + createdAt_gte?: DateTime | null + createdById_eq?: ID_Input | null + createdById_in?: ID_Output[] | ID_Output | null + updatedAt_eq?: DateTime | null + updatedAt_lt?: DateTime | null + updatedAt_lte?: DateTime | null + updatedAt_gt?: DateTime | null + updatedAt_gte?: DateTime | null + updatedById_eq?: ID_Input | null + updatedById_in?: ID_Output[] | ID_Output | null deletedAt_all?: Boolean | null - deletedAt_eq?: String | null - deletedAt_lt?: String | null - deletedAt_lte?: String | null - deletedAt_gt?: String | null - deletedAt_gte?: String | null - deletedById_eq?: String | null + deletedAt_eq?: DateTime | null + deletedAt_lt?: DateTime | null + deletedAt_lte?: DateTime | null + deletedAt_gt?: DateTime | null + deletedAt_gte?: DateTime | null + deletedById_eq?: ID_Input | null + deletedById_in?: ID_Output[] | ID_Output | null username_eq?: String | null username_contains?: String | null username_startsWith?: String | null @@ -303,10 +432,12 @@ export interface UserWhereInput { bio_startsWith?: String | null bio_endsWith?: String | null bio_in?: String[] | String | null + accountSettings_json?: JSONObject | null } export interface UserWhereUniqueInput { - id: String + id?: ID_Input | null + email?: String | null } export interface BaseGraphQLObject { @@ -361,6 +492,13 @@ export interface CollectionItem extends BaseGraphQLObject { userId: String itemDetails?: Item | null itemDetailsId: String + plays?: Int | null + mbid?: String | null + reviews?: Array | null + artist: String + title: String + rating: String + reviewBody: String } export interface Item extends BaseGraphQLObject { @@ -375,12 +513,37 @@ export interface Item extends BaseGraphQLObject { mbid?: String | null rymId?: Int | null spotifyId?: String | null - title?: String | null + title: String disambiguation?: String | null - artist?: String | null + artist: String + coverArt?: String | null collectionItem?: Array | null } +export interface PageInfo { + limit: Float + offset: Float + totalCount: Float + hasNextPage: Boolean + hasPreviousPage: Boolean +} + +export interface Review extends BaseGraphQLObject { + id: ID_Output + createdAt: DateTime + createdById: String + updatedAt?: DateTime | null + updatedById?: String | null + deletedAt?: DateTime | null + deletedById?: String | null + version: Int + collectionItem?: CollectionItem | null + collectionItemId: String + rating?: String | null + title?: String | null + body?: String | null +} + export interface StandardDeleteResponse { id: ID_Output } @@ -397,6 +560,7 @@ export interface User extends BaseGraphQLObject { username: String email?: String | null bio?: String | null + accountSettings?: JSONObject | null collection?: Array | null } @@ -426,6 +590,22 @@ The `Int` scalar type represents non-fractional signed whole numeric values. Int */ export type Int = number +/* +The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +*/ + + export type JsonValue = JsonPrimitive | JsonObject | JsonArray; + + export type JsonPrimitive = string | number | boolean | null | {}; + + // eslint-disable-next-line @typescript-eslint/no-empty-interface + export interface JsonArray extends Array {} + + export type JsonObject = { [member: string]: JsonValue }; + + export type JSONObject = JsonObject; + + /* The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text. */ diff --git a/generated/classes.ts b/generated/classes.ts index 7d68af5..36ec78c 100644 --- a/generated/classes.ts +++ b/generated/classes.ts @@ -3,8 +3,8 @@ // new TypeGraphQL objects // @ts-ignore import { GraphQLDateTime as DateTime } from "graphql-iso-date"; +// @ts-ignore import { GraphQLID as ID } from "graphql"; - // @ts-ignore import { ArgsType, @@ -26,6 +26,8 @@ import { User } from "../src/modules/user/user.model"; // @ts-ignore import { Item } from "../src/modules/item/item.model"; // @ts-ignore +import { Review } from "../src/modules/review/review.model"; +// @ts-ignore import { CollectionItem } from "../src/modules/collection-item/collection-item.model"; export enum UserOrderByEnum { @@ -54,69 +56,78 @@ registerEnumType(UserOrderByEnum, { @TypeGraphQLInputType() export class UserWhereInput { - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) id_eq?: string; - @TypeGraphQLField(() => [String], { nullable: true }) + @TypeGraphQLField(() => [ID], { nullable: true }) id_in?: string[]; @TypeGraphQLField({ nullable: true }) - createdAt_eq?: String; + createdAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_lt?: String; + createdAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_lte?: String; + createdAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_gt?: String; + createdAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_gte?: String; + createdAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) createdById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + createdById_in?: string[]; + @TypeGraphQLField({ nullable: true }) - updatedAt_eq?: String; + updatedAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_lt?: String; + updatedAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_lte?: String; + updatedAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_gt?: String; + updatedAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_gte?: String; + updatedAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) updatedById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + updatedById_in?: string[]; + @TypeGraphQLField({ nullable: true }) deletedAt_all?: Boolean; @TypeGraphQLField({ nullable: true }) - deletedAt_eq?: String; + deletedAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_lt?: String; + deletedAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_lte?: String; + deletedAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_gt?: String; + deletedAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_gte?: String; + deletedAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) deletedById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + deletedById_in?: string[]; + @TypeGraphQLField({ nullable: true }) username_eq?: string; @@ -161,12 +172,18 @@ export class UserWhereInput { @TypeGraphQLField(() => [String], { nullable: true }) bio_in?: string[]; + + @TypeGraphQLField(() => GraphQLJSONObject, { nullable: true }) + accountSettings_json?: JsonObject; } @TypeGraphQLInputType() export class UserWhereUniqueInput { - @TypeGraphQLField(() => String) + @TypeGraphQLField(() => ID, { nullable: true }) id?: string; + + @TypeGraphQLField(() => String, { nullable: true }) + email?: string; } @TypeGraphQLInputType() @@ -177,8 +194,14 @@ export class UserCreateInput { @TypeGraphQLField({ nullable: true }) email?: string; + @TypeGraphQLField() + password!: string; + @TypeGraphQLField({ nullable: true }) bio?: string; + + @TypeGraphQLField(() => GraphQLJSONObject, { nullable: true }) + accountSettings?: JsonObject; } @TypeGraphQLInputType() @@ -189,8 +212,14 @@ export class UserUpdateInput { @TypeGraphQLField({ nullable: true }) email?: string; + @TypeGraphQLField({ nullable: true }) + password?: string; + @TypeGraphQLField({ nullable: true }) bio?: string; + + @TypeGraphQLField(() => GraphQLJSONObject, { nullable: true }) + accountSettings?: JsonObject; } @ArgsType() @@ -240,7 +269,10 @@ export enum ItemOrderByEnum { disambiguation_DESC = "disambiguation_DESC", artist_ASC = "artist_ASC", - artist_DESC = "artist_DESC" + artist_DESC = "artist_DESC", + + coverArt_ASC = "coverArt_ASC", + coverArt_DESC = "coverArt_DESC" } registerEnumType(ItemOrderByEnum, { @@ -249,69 +281,78 @@ registerEnumType(ItemOrderByEnum, { @TypeGraphQLInputType() export class ItemWhereInput { - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) id_eq?: string; - @TypeGraphQLField(() => [String], { nullable: true }) + @TypeGraphQLField(() => [ID], { nullable: true }) id_in?: string[]; @TypeGraphQLField({ nullable: true }) - createdAt_eq?: String; + createdAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_lt?: String; + createdAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_lte?: String; + createdAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_gt?: String; + createdAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_gte?: String; + createdAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) createdById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + createdById_in?: string[]; + @TypeGraphQLField({ nullable: true }) - updatedAt_eq?: String; + updatedAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_lt?: String; + updatedAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_lte?: String; + updatedAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_gt?: String; + updatedAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_gte?: String; + updatedAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) updatedById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + updatedById_in?: string[]; + @TypeGraphQLField({ nullable: true }) deletedAt_all?: Boolean; @TypeGraphQLField({ nullable: true }) - deletedAt_eq?: String; + deletedAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_lt?: String; + deletedAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_lte?: String; + deletedAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_gt?: String; + deletedAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_gte?: String; + deletedAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) deletedById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + deletedById_in?: string[]; + @TypeGraphQLField({ nullable: true }) mbid_eq?: string; @@ -345,10 +386,19 @@ export class ItemWhereInput { @TypeGraphQLField(() => [Int], { nullable: true }) rymId_in?: number[]; - @TypeGraphQLField(() => ID, { nullable: true }) + @TypeGraphQLField({ nullable: true }) spotifyId_eq?: string; - @TypeGraphQLField(() => [ID], { nullable: true }) + @TypeGraphQLField({ nullable: true }) + spotifyId_contains?: string; + + @TypeGraphQLField({ nullable: true }) + spotifyId_startsWith?: string; + + @TypeGraphQLField({ nullable: true }) + spotifyId_endsWith?: string; + + @TypeGraphQLField(() => [String], { nullable: true }) spotifyId_in?: string[]; @TypeGraphQLField({ nullable: true }) @@ -395,11 +445,26 @@ export class ItemWhereInput { @TypeGraphQLField(() => [String], { nullable: true }) artist_in?: string[]; + + @TypeGraphQLField({ nullable: true }) + coverArt_eq?: string; + + @TypeGraphQLField({ nullable: true }) + coverArt_contains?: string; + + @TypeGraphQLField({ nullable: true }) + coverArt_startsWith?: string; + + @TypeGraphQLField({ nullable: true }) + coverArt_endsWith?: string; + + @TypeGraphQLField(() => [String], { nullable: true }) + coverArt_in?: string[]; } @TypeGraphQLInputType() export class ItemWhereUniqueInput { - @TypeGraphQLField(() => String) + @TypeGraphQLField(() => ID) id?: string; } @@ -411,17 +476,20 @@ export class ItemCreateInput { @TypeGraphQLField({ nullable: true }) rymId?: number; - @TypeGraphQLField(() => ID, { nullable: true }) + @TypeGraphQLField({ nullable: true }) spotifyId?: string; - @TypeGraphQLField({ nullable: true }) - title?: string; + @TypeGraphQLField() + title!: string; @TypeGraphQLField({ nullable: true }) disambiguation?: string; + @TypeGraphQLField() + artist!: string; + @TypeGraphQLField({ nullable: true }) - artist?: string; + coverArt?: string; } @TypeGraphQLInputType() @@ -432,7 +500,7 @@ export class ItemUpdateInput { @TypeGraphQLField({ nullable: true }) rymId?: number; - @TypeGraphQLField(() => ID, { nullable: true }) + @TypeGraphQLField({ nullable: true }) spotifyId?: string; @TypeGraphQLField({ nullable: true }) @@ -443,6 +511,9 @@ export class ItemUpdateInput { @TypeGraphQLField({ nullable: true }) artist?: string; + + @TypeGraphQLField({ nullable: true }) + coverArt?: string; } @ArgsType() @@ -466,6 +537,216 @@ export class ItemUpdateArgs { @TypeGraphQLField() where!: ItemWhereUniqueInput; } +export enum ReviewOrderByEnum { + createdAt_ASC = "createdAt_ASC", + createdAt_DESC = "createdAt_DESC", + + updatedAt_ASC = "updatedAt_ASC", + updatedAt_DESC = "updatedAt_DESC", + + deletedAt_ASC = "deletedAt_ASC", + deletedAt_DESC = "deletedAt_DESC", + + collectionItemId_ASC = "collectionItemId_ASC", + collectionItemId_DESC = "collectionItemId_DESC", + + rating_ASC = "rating_ASC", + rating_DESC = "rating_DESC", + + title_ASC = "title_ASC", + title_DESC = "title_DESC", + + body_ASC = "body_ASC", + body_DESC = "body_DESC" +} + +registerEnumType(ReviewOrderByEnum, { + name: "ReviewOrderByInput" +}); + +@TypeGraphQLInputType() +export class ReviewWhereInput { + @TypeGraphQLField(() => ID, { nullable: true }) + id_eq?: string; + + @TypeGraphQLField(() => [ID], { nullable: true }) + id_in?: string[]; + + @TypeGraphQLField({ nullable: true }) + createdAt_eq?: Date; + + @TypeGraphQLField({ nullable: true }) + createdAt_lt?: Date; + + @TypeGraphQLField({ nullable: true }) + createdAt_lte?: Date; + + @TypeGraphQLField({ nullable: true }) + createdAt_gt?: Date; + + @TypeGraphQLField({ nullable: true }) + createdAt_gte?: Date; + + @TypeGraphQLField(() => ID, { nullable: true }) + createdById_eq?: string; + + @TypeGraphQLField(() => [ID], { nullable: true }) + createdById_in?: string[]; + + @TypeGraphQLField({ nullable: true }) + updatedAt_eq?: Date; + + @TypeGraphQLField({ nullable: true }) + updatedAt_lt?: Date; + + @TypeGraphQLField({ nullable: true }) + updatedAt_lte?: Date; + + @TypeGraphQLField({ nullable: true }) + updatedAt_gt?: Date; + + @TypeGraphQLField({ nullable: true }) + updatedAt_gte?: Date; + + @TypeGraphQLField(() => ID, { nullable: true }) + updatedById_eq?: string; + + @TypeGraphQLField(() => [ID], { nullable: true }) + updatedById_in?: string[]; + + @TypeGraphQLField({ nullable: true }) + deletedAt_all?: Boolean; + + @TypeGraphQLField({ nullable: true }) + deletedAt_eq?: Date; + + @TypeGraphQLField({ nullable: true }) + deletedAt_lt?: Date; + + @TypeGraphQLField({ nullable: true }) + deletedAt_lte?: Date; + + @TypeGraphQLField({ nullable: true }) + deletedAt_gt?: Date; + + @TypeGraphQLField({ nullable: true }) + deletedAt_gte?: Date; + + @TypeGraphQLField(() => ID, { nullable: true }) + deletedById_eq?: string; + + @TypeGraphQLField(() => [ID], { nullable: true }) + deletedById_in?: string[]; + + @TypeGraphQLField(() => ID, { nullable: true }) + collectionItemId_eq?: string; + + @TypeGraphQLField(() => [ID], { nullable: true }) + collectionItemId_in?: string[]; + + @TypeGraphQLField({ nullable: true }) + rating_eq?: string; + + @TypeGraphQLField({ nullable: true }) + rating_contains?: string; + + @TypeGraphQLField({ nullable: true }) + rating_startsWith?: string; + + @TypeGraphQLField({ nullable: true }) + rating_endsWith?: string; + + @TypeGraphQLField(() => [String], { nullable: true }) + rating_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 }) + body_eq?: string; + + @TypeGraphQLField({ nullable: true }) + body_contains?: string; + + @TypeGraphQLField({ nullable: true }) + body_startsWith?: string; + + @TypeGraphQLField({ nullable: true }) + body_endsWith?: string; + + @TypeGraphQLField(() => [String], { nullable: true }) + body_in?: string[]; +} + +@TypeGraphQLInputType() +export class ReviewWhereUniqueInput { + @TypeGraphQLField(() => ID) + id?: string; +} + +@TypeGraphQLInputType() +export class ReviewCreateInput { + @TypeGraphQLField(() => ID) + collectionItemId!: string; + + @TypeGraphQLField({ nullable: true }) + rating?: string; + + @TypeGraphQLField({ nullable: true }) + title?: string; + + @TypeGraphQLField({ nullable: true }) + body?: string; +} + +@TypeGraphQLInputType() +export class ReviewUpdateInput { + @TypeGraphQLField(() => ID, { nullable: true }) + collectionItemId?: string; + + @TypeGraphQLField({ nullable: true }) + rating?: string; + + @TypeGraphQLField({ nullable: true }) + title?: string; + + @TypeGraphQLField({ nullable: true }) + body?: string; +} + +@ArgsType() +export class ReviewWhereArgs extends PaginationArgs { + @TypeGraphQLField(() => ReviewWhereInput, { nullable: true }) + where?: ReviewWhereInput; + + @TypeGraphQLField(() => ReviewOrderByEnum, { nullable: true }) + orderBy?: ReviewOrderByEnum; +} + +@ArgsType() +export class ReviewCreateManyArgs { + @TypeGraphQLField(() => [ReviewCreateInput]) + data!: ReviewCreateInput[]; +} + +@ArgsType() +export class ReviewUpdateArgs { + @TypeGraphQLField() data!: ReviewUpdateInput; + @TypeGraphQLField() where!: ReviewWhereUniqueInput; +} + export enum CollectionItemOrderByEnum { createdAt_ASC = "createdAt_ASC", createdAt_DESC = "createdAt_DESC", @@ -486,7 +767,13 @@ export enum CollectionItemOrderByEnum { userId_DESC = "userId_DESC", itemDetailsId_ASC = "itemDetailsId_ASC", - itemDetailsId_DESC = "itemDetailsId_DESC" + itemDetailsId_DESC = "itemDetailsId_DESC", + + plays_ASC = "plays_ASC", + plays_DESC = "plays_DESC", + + mbid_ASC = "mbid_ASC", + mbid_DESC = "mbid_DESC" } registerEnumType(CollectionItemOrderByEnum, { @@ -495,69 +782,78 @@ registerEnumType(CollectionItemOrderByEnum, { @TypeGraphQLInputType() export class CollectionItemWhereInput { - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) id_eq?: string; - @TypeGraphQLField(() => [String], { nullable: true }) + @TypeGraphQLField(() => [ID], { nullable: true }) id_in?: string[]; @TypeGraphQLField({ nullable: true }) - createdAt_eq?: String; + createdAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_lt?: String; + createdAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_lte?: String; + createdAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_gt?: String; + createdAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - createdAt_gte?: String; + createdAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) createdById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + createdById_in?: string[]; + @TypeGraphQLField({ nullable: true }) - updatedAt_eq?: String; + updatedAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_lt?: String; + updatedAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_lte?: String; + updatedAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_gt?: String; + updatedAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - updatedAt_gte?: String; + updatedAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) updatedById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + updatedById_in?: string[]; + @TypeGraphQLField({ nullable: true }) deletedAt_all?: Boolean; @TypeGraphQLField({ nullable: true }) - deletedAt_eq?: String; + deletedAt_eq?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_lt?: String; + deletedAt_lt?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_lte?: String; + deletedAt_lte?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_gt?: String; + deletedAt_gt?: Date; @TypeGraphQLField({ nullable: true }) - deletedAt_gte?: String; + deletedAt_gte?: Date; - @TypeGraphQLField(() => String, { nullable: true }) + @TypeGraphQLField(() => ID, { nullable: true }) deletedById_eq?: string; + @TypeGraphQLField(() => [ID], { nullable: true }) + deletedById_in?: string[]; + @TypeGraphQLField({ nullable: true }) customTitle_eq?: string; @@ -599,11 +895,44 @@ export class CollectionItemWhereInput { @TypeGraphQLField(() => [ID], { nullable: true }) itemDetailsId_in?: string[]; + + @TypeGraphQLField(() => Int, { nullable: true }) + plays_eq?: number; + + @TypeGraphQLField(() => Int, { nullable: true }) + plays_gt?: number; + + @TypeGraphQLField(() => Int, { nullable: true }) + plays_gte?: number; + + @TypeGraphQLField(() => Int, { nullable: true }) + plays_lt?: number; + + @TypeGraphQLField(() => Int, { nullable: true }) + plays_lte?: number; + + @TypeGraphQLField(() => [Int], { nullable: true }) + plays_in?: number[]; + + @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() export class CollectionItemWhereUniqueInput { - @TypeGraphQLField(() => String) + @TypeGraphQLField(() => ID) id?: string; } @@ -620,6 +949,12 @@ export class CollectionItemCreateInput { @TypeGraphQLField(() => ID) itemDetailsId!: string; + + @TypeGraphQLField({ nullable: true }) + plays?: number; + + @TypeGraphQLField({ nullable: true }) + mbid?: string; } @TypeGraphQLInputType() @@ -635,6 +970,12 @@ export class CollectionItemUpdateInput { @TypeGraphQLField(() => ID, { nullable: true }) itemDetailsId?: string; + + @TypeGraphQLField({ nullable: true }) + plays?: number; + + @TypeGraphQLField({ nullable: true }) + mbid?: string; } @ArgsType() diff --git a/generated/schema.graphql b/generated/schema.graphql index 87bf0fb..7831c61 100644 --- a/generated/schema.graphql +++ b/generated/schema.graphql @@ -70,6 +70,13 @@ type CollectionItem implements BaseGraphQLObject { userId: String! itemDetails: Item itemDetailsId: String! + plays: Int + mbid: String + reviews: [Review!] + artist: String! + title: String! + rating: String! + reviewBody: String! } input CollectionItemCreateInput { @@ -77,6 +84,8 @@ input CollectionItemCreateInput { customArtist: String userId: ID! itemDetailsId: ID! + plays: Float + mbid: String } enum CollectionItemOrderByInput { @@ -94,6 +103,10 @@ enum CollectionItemOrderByInput { userId_DESC itemDetailsId_ASC itemDetailsId_DESC + plays_ASC + plays_DESC + mbid_ASC + mbid_DESC } input CollectionItemUpdateInput { @@ -101,30 +114,35 @@ input CollectionItemUpdateInput { customArtist: String userId: ID itemDetailsId: ID + plays: Float + mbid: String } input CollectionItemWhereInput { - id_eq: String - id_in: [String!] - createdAt_eq: String - createdAt_lt: String - createdAt_lte: String - createdAt_gt: String - createdAt_gte: String - createdById_eq: String - updatedAt_eq: String - updatedAt_lt: String - updatedAt_lte: String - updatedAt_gt: String - updatedAt_gte: String - updatedById_eq: String + id_eq: ID + id_in: [ID!] + createdAt_eq: DateTime + createdAt_lt: DateTime + createdAt_lte: DateTime + createdAt_gt: DateTime + createdAt_gte: DateTime + createdById_eq: ID + createdById_in: [ID!] + updatedAt_eq: DateTime + updatedAt_lt: DateTime + updatedAt_lte: DateTime + updatedAt_gt: DateTime + updatedAt_gte: DateTime + updatedById_eq: ID + updatedById_in: [ID!] deletedAt_all: Boolean - deletedAt_eq: String - deletedAt_lt: String - deletedAt_lte: String - deletedAt_gt: String - deletedAt_gte: String - deletedById_eq: String + deletedAt_eq: DateTime + deletedAt_lt: DateTime + deletedAt_lte: DateTime + deletedAt_gt: DateTime + deletedAt_gte: DateTime + deletedById_eq: ID + deletedById_in: [ID!] customTitle_eq: String customTitle_contains: String customTitle_startsWith: String @@ -139,10 +157,21 @@ input CollectionItemWhereInput { userId_in: [ID!] itemDetailsId_eq: ID itemDetailsId_in: [ID!] + plays_eq: Int + plays_gt: Int + plays_gte: Int + plays_lt: Int + plays_lte: Int + plays_in: [Int!] + mbid_eq: String + mbid_contains: String + mbid_startsWith: String + mbid_endsWith: String + mbid_in: [String!] } input CollectionItemWhereUniqueInput { - id: String! + id: ID! } """ @@ -166,19 +195,21 @@ type Item implements BaseGraphQLObject { mbid: String rymId: Int spotifyId: String - title: String + title: String! disambiguation: String - artist: String + artist: String! + coverArt: String collectionItem: [CollectionItem!] } input ItemCreateInput { mbid: String rymId: Float - spotifyId: ID - title: String + spotifyId: String + title: String! disambiguation: String - artist: String + artist: String! + coverArt: String } enum ItemOrderByInput { @@ -200,39 +231,45 @@ enum ItemOrderByInput { disambiguation_DESC artist_ASC artist_DESC + coverArt_ASC + coverArt_DESC } input ItemUpdateInput { mbid: String rymId: Float - spotifyId: ID + spotifyId: String title: String disambiguation: String artist: String + coverArt: String } input ItemWhereInput { - id_eq: String - id_in: [String!] - createdAt_eq: String - createdAt_lt: String - createdAt_lte: String - createdAt_gt: String - createdAt_gte: String - createdById_eq: String - updatedAt_eq: String - updatedAt_lt: String - updatedAt_lte: String - updatedAt_gt: String - updatedAt_gte: String - updatedById_eq: String + id_eq: ID + id_in: [ID!] + createdAt_eq: DateTime + createdAt_lt: DateTime + createdAt_lte: DateTime + createdAt_gt: DateTime + createdAt_gte: DateTime + createdById_eq: ID + createdById_in: [ID!] + updatedAt_eq: DateTime + updatedAt_lt: DateTime + updatedAt_lte: DateTime + updatedAt_gt: DateTime + updatedAt_gte: DateTime + updatedById_eq: ID + updatedById_in: [ID!] deletedAt_all: Boolean - deletedAt_eq: String - deletedAt_lt: String - deletedAt_lte: String - deletedAt_gt: String - deletedAt_gte: String - deletedById_eq: String + deletedAt_eq: DateTime + deletedAt_lt: DateTime + deletedAt_lte: DateTime + deletedAt_gt: DateTime + deletedAt_gte: DateTime + deletedById_eq: ID + deletedById_in: [ID!] mbid_eq: String mbid_contains: String mbid_startsWith: String @@ -244,8 +281,11 @@ input ItemWhereInput { rymId_lt: Int rymId_lte: Int rymId_in: [Int!] - spotifyId_eq: ID - spotifyId_in: [ID!] + spotifyId_eq: String + spotifyId_contains: String + spotifyId_startsWith: String + spotifyId_endsWith: String + spotifyId_in: [String!] title_eq: String title_contains: String title_startsWith: String @@ -261,12 +301,22 @@ input ItemWhereInput { artist_startsWith: String artist_endsWith: String artist_in: [String!] + coverArt_eq: String + coverArt_contains: String + coverArt_startsWith: String + coverArt_endsWith: String + coverArt_in: [String!] } input ItemWhereUniqueInput { - id: String! + id: ID! } +""" +The `JSONObject` scalar type represents JSON objects as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). +""" +scalar JSONObject + type Mutation { createCollectionItem(data: CollectionItemCreateInput!): CollectionItem! createManyCollectionItems(data: [CollectionItemCreateInput!]!): [CollectionItem!]! @@ -276,21 +326,130 @@ type Mutation { createManyItems(data: [ItemCreateInput!]!): [Item!]! updateItem(data: ItemUpdateInput!, where: ItemWhereUniqueInput!): Item! deleteItem(where: ItemWhereUniqueInput!): StandardDeleteResponse! + createReview(data: ReviewCreateInput!): Review! + createManyReviews(data: [ReviewCreateInput!]!): [Review!]! + updateReview(data: ReviewUpdateInput!, where: ReviewWhereUniqueInput!): Review! + deleteReview(where: ReviewWhereUniqueInput!): StandardDeleteResponse! createUser(data: UserCreateInput!): User! createManyUsers(data: [UserCreateInput!]!): [User!]! updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User! deleteUser(where: UserWhereUniqueInput!): StandardDeleteResponse! } +type PageInfo { + limit: Float! + offset: Float! + totalCount: Float! + hasNextPage: Boolean! + hasPreviousPage: Boolean! +} + type Query { collectionItems(offset: Int, limit: Int = 50, where: CollectionItemWhereInput, orderBy: CollectionItemOrderByInput): [CollectionItem!]! collectionItem(where: CollectionItemWhereUniqueInput!): CollectionItem! items(offset: Int, limit: Int = 50, where: ItemWhereInput, orderBy: ItemOrderByInput): [Item!]! item(where: ItemWhereUniqueInput!): Item! + reviews(offset: Int, limit: Int = 50, where: ReviewWhereInput, orderBy: ReviewOrderByInput): [Review!]! + review(where: ReviewWhereUniqueInput!): Review! users(offset: Int, limit: Int = 50, where: UserWhereInput, orderBy: UserOrderByInput): [User!]! user(where: UserWhereUniqueInput!): User! } +type Review implements BaseGraphQLObject { + id: ID! + createdAt: DateTime! + createdById: String! + updatedAt: DateTime + updatedById: String + deletedAt: DateTime + deletedById: String + version: Int! + collectionItem: CollectionItem + collectionItemId: String! + rating: String + title: String + body: String +} + +input ReviewCreateInput { + collectionItemId: ID! + rating: String + title: String + body: String +} + +enum ReviewOrderByInput { + createdAt_ASC + createdAt_DESC + updatedAt_ASC + updatedAt_DESC + deletedAt_ASC + deletedAt_DESC + collectionItemId_ASC + collectionItemId_DESC + rating_ASC + rating_DESC + title_ASC + title_DESC + body_ASC + body_DESC +} + +input ReviewUpdateInput { + collectionItemId: ID + rating: String + title: String + body: String +} + +input ReviewWhereInput { + id_eq: ID + id_in: [ID!] + createdAt_eq: DateTime + createdAt_lt: DateTime + createdAt_lte: DateTime + createdAt_gt: DateTime + createdAt_gte: DateTime + createdById_eq: ID + createdById_in: [ID!] + updatedAt_eq: DateTime + updatedAt_lt: DateTime + updatedAt_lte: DateTime + updatedAt_gt: DateTime + updatedAt_gte: DateTime + updatedById_eq: ID + updatedById_in: [ID!] + deletedAt_all: Boolean + deletedAt_eq: DateTime + deletedAt_lt: DateTime + deletedAt_lte: DateTime + deletedAt_gt: DateTime + deletedAt_gte: DateTime + deletedById_eq: ID + deletedById_in: [ID!] + collectionItemId_eq: ID + collectionItemId_in: [ID!] + rating_eq: String + rating_contains: String + rating_startsWith: String + rating_endsWith: String + rating_in: [String!] + title_eq: String + title_contains: String + title_startsWith: String + title_endsWith: String + title_in: [String!] + body_eq: String + body_contains: String + body_startsWith: String + body_endsWith: String + body_in: [String!] +} + +input ReviewWhereUniqueInput { + id: ID! +} + type StandardDeleteResponse { id: ID! } @@ -307,13 +466,16 @@ type User implements BaseGraphQLObject { username: String! email: String bio: String + accountSettings: JSONObject collection: [CollectionItem!] } input UserCreateInput { username: String! email: String + password: String! bio: String + accountSettings: JSONObject } enum UserOrderByInput { @@ -334,31 +496,36 @@ enum UserOrderByInput { input UserUpdateInput { username: String email: String + password: String bio: String + accountSettings: JSONObject } input UserWhereInput { - id_eq: String - id_in: [String!] - createdAt_eq: String - createdAt_lt: String - createdAt_lte: String - createdAt_gt: String - createdAt_gte: String - createdById_eq: String - updatedAt_eq: String - updatedAt_lt: String - updatedAt_lte: String - updatedAt_gt: String - updatedAt_gte: String - updatedById_eq: String + id_eq: ID + id_in: [ID!] + createdAt_eq: DateTime + createdAt_lt: DateTime + createdAt_lte: DateTime + createdAt_gt: DateTime + createdAt_gte: DateTime + createdById_eq: ID + createdById_in: [ID!] + updatedAt_eq: DateTime + updatedAt_lt: DateTime + updatedAt_lte: DateTime + updatedAt_gt: DateTime + updatedAt_gte: DateTime + updatedById_eq: ID + updatedById_in: [ID!] deletedAt_all: Boolean - deletedAt_eq: String - deletedAt_lt: String - deletedAt_lte: String - deletedAt_gt: String - deletedAt_gte: String - deletedById_eq: String + deletedAt_eq: DateTime + deletedAt_lt: DateTime + deletedAt_lte: DateTime + deletedAt_gt: DateTime + deletedAt_gte: DateTime + deletedById_eq: ID + deletedById_in: [ID!] username_eq: String username_contains: String username_startsWith: String @@ -374,8 +541,10 @@ input UserWhereInput { bio_startsWith: String bio_endsWith: String bio_in: [String!] + accountSettings_json: JSONObject } input UserWhereUniqueInput { - id: String! + id: ID + email: String } diff --git a/package.json b/package.json index 4cbe159..1ed8207 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,9 @@ { "name": "patrician-api", - "version": "0.0.0", - "description": "Generated Warthog Project", + "version": "0.1.0", + "description": "Patrician API", "license": "MIT", + "author": "Patrician Team", "scripts": { "bootstrap": "yarn bootstrap:dev", "bootstrap:dev": "yarn && yarn build:dev && yarn db:drop && yarn db:create && yarn db:migrate && yarn db:seed", @@ -57,11 +58,13 @@ ] }, "dependencies": { + "@types/bcrypt": "^3.0.0", "@types/sqlite3": "^3.1.5", + "bcrypt": "^4.0.1", "dotenv": "^8.0.0", "dotenvi": "^0.6.0", "reflect-metadata": "^0.1.13", - "warthog": "^2.1.1" + "warthog": "^2.6.0" }, "devDependencies": { "@types/jest": "^24.0.15", @@ -101,5 +104,9 @@ }, "resolutions": { "ts-node": "7.0.1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/patricianapp/patrician-api.git" } } diff --git a/src/interfaces/account-settings.ts b/src/interfaces/account-settings.ts new file mode 100644 index 0000000..81a3300 --- /dev/null +++ b/src/interfaces/account-settings.ts @@ -0,0 +1,3 @@ +export interface AccountSettings { + itemsPerPage: number; +} \ No newline at end of file diff --git a/src/modules/collection-item/collection-item.model.ts b/src/modules/collection-item/collection-item.model.ts index f350574..2899d16 100644 --- a/src/modules/collection-item/collection-item.model.ts +++ b/src/modules/collection-item/collection-item.model.ts @@ -1,6 +1,7 @@ -import { BaseModel, Model, StringField, ManyToOne } from 'warthog'; +import { BaseModel, Model, StringField, ManyToOne, OneToMany, IntField } from 'warthog'; import { User } from '../user/user.model'; import { Item } from '../item/item.model'; +import { Review } from '../review/review.model'; @Model() export class CollectionItem extends BaseModel { @@ -14,11 +15,52 @@ export class CollectionItem extends BaseModel { () => User, (user: User) => user.collection ) - user?: User; + user!: User; @ManyToOne( () => Item, (item: Item) => item.collectionItem ) - itemDetails?: Item; + itemDetails!: Item; + + @IntField({ nullable: true, default: 0 }) + plays?: number + + // 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; + // } + + // 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 { + return this.itemDetails.mbid; + } + + @OneToMany( + () => Review, + (review: Review) => review.collectionItem + ) + reviews?: Review[]; + + // 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? + // } + + // @StringField({ apiOnly: true, nullable: true }) + // get review(): string | undefined { + // return this.reviews?.pop()?.reviewText; + // } } 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/item/item.model.ts b/src/modules/item/item.model.ts index 5f32562..afc2da7 100644 --- a/src/modules/item/item.model.ts +++ b/src/modules/item/item.model.ts @@ -12,14 +12,17 @@ export class Item extends BaseModel { @StringField({ nullable: true }) spotifyId?: string; - @StringField({ nullable: true }) - title?: string; + @StringField() + title!: string; @StringField({ nullable: true }) disambiguation?: string; + @StringField() + artist!: string; + @StringField({ nullable: true }) - artist?: string; + coverArt?: string; @OneToMany( () => CollectionItem, diff --git a/src/modules/review/review.model.ts b/src/modules/review/review.model.ts new file mode 100644 index 0000000..77f1df2 --- /dev/null +++ b/src/modules/review/review.model.ts @@ -0,0 +1,20 @@ +import { BaseModel, Model, StringField, ManyToOne } from 'warthog'; +import { CollectionItem } from '../collection-item/collection-item.model'; + +@Model() +export class Review extends BaseModel { + @ManyToOne( + () => CollectionItem, + (collectionItem: CollectionItem) => collectionItem.reviews + ) + collectionItem!: CollectionItem; + + @StringField({ nullable: true }) + rating?: string; + + @StringField({ nullable: true }) + title?: string; + + @StringField({ nullable: true }) + body?: string; +} diff --git a/src/modules/review/review.resolver.ts b/src/modules/review/review.resolver.ts new file mode 100644 index 0000000..28d8881 --- /dev/null +++ b/src/modules/review/review.resolver.ts @@ -0,0 +1,65 @@ +import { Arg, Args, Mutation, Query, Resolver } from 'type-graphql'; +import { Inject } from 'typedi'; +import { Fields, StandardDeleteResponse, UserId } from 'warthog'; + +import { + ReviewCreateInput, + ReviewCreateManyArgs, + ReviewUpdateArgs, + ReviewWhereArgs, + ReviewWhereInput, + ReviewWhereUniqueInput +} from '../../../generated'; + +import { Review } from './review.model'; +import { ReviewService } from './review.service'; + +@Resolver(Review) +export class ReviewResolver { + constructor(@Inject('ReviewService') public readonly service: ReviewService) {} + + @Query(() => [Review]) + async reviews( + @Args() { where, orderBy, limit, offset }: ReviewWhereArgs, + @Fields() fields: string[] + ): Promise { + return this.service.find(where, orderBy, limit, offset, fields); + } + + @Query(() => Review) + async review(@Arg('where') where: ReviewWhereUniqueInput): Promise { + return this.service.findOne(where); + } + + @Mutation(() => Review) + async createReview( + @Arg('data') data: ReviewCreateInput, + @UserId() userId: string + ): Promise { + return this.service.create(data, userId); + } + + @Mutation(() => [Review]) + async createManyReviews( + @Args() { data }: ReviewCreateManyArgs, + @UserId() userId: string + ): Promise { + return this.service.createMany(data, userId); + } + + @Mutation(() => Review) + async updateReview( + @Args() { data, where }: ReviewUpdateArgs, + @UserId() userId: string + ): Promise { + return this.service.update(data, where, userId); + } + + @Mutation(() => StandardDeleteResponse) + async deleteReview( + @Arg('where') where: ReviewWhereUniqueInput, + @UserId() userId: string + ): Promise { + return this.service.delete(where, userId); + } +} diff --git a/src/modules/review/review.service.ts b/src/modules/review/review.service.ts new file mode 100644 index 0000000..ce3e399 --- /dev/null +++ b/src/modules/review/review.service.ts @@ -0,0 +1,13 @@ +import { Service } from 'typedi'; +import { Repository } from 'typeorm'; +import { InjectRepository } from 'typeorm-typedi-extensions'; +import { BaseService } from 'warthog'; + +import { Review } from './review.model'; + +@Service('ReviewService') +export class ReviewService extends BaseService { + constructor(@InjectRepository(Review) protected readonly repository: Repository) { + super(Review, repository); + } +} diff --git a/src/modules/user/user.model.ts b/src/modules/user/user.model.ts index 0ea0d11..0e7294c 100644 --- a/src/modules/user/user.model.ts +++ b/src/modules/user/user.model.ts @@ -1,17 +1,27 @@ -import { BaseModel, Model, OneToMany, StringField } from 'warthog'; +import { BaseModel, Model, OneToMany, StringField, EmailField, JSONField } from 'warthog'; import { CollectionItem } from '../collection-item/collection-item.model'; +import { AccountSettings } from '../../interfaces/account-settings'; @Model() export class User extends BaseModel { @StringField() username!: string; - @StringField({ nullable: true }) + @EmailField({ nullable: true }) email?: string; + @StringField({ writeonly: true }) + password!: string; + + @StringField({ dbOnly: true }) + salt!: string; + @StringField({ nullable: true }) bio?: string; + @JSONField({ nullable: true }) + accountSettings?: AccountSettings; + @OneToMany( () => CollectionItem, (collectionItem: CollectionItem) => collectionItem.user diff --git a/src/modules/user/user.service.ts b/src/modules/user/user.service.ts index 6676c8a..be69645 100644 --- a/src/modules/user/user.service.ts +++ b/src/modules/user/user.service.ts @@ -2,12 +2,40 @@ import { Service } from 'typedi'; import { Repository } from 'typeorm'; import { InjectRepository } from 'typeorm-typedi-extensions'; import { BaseService } from 'warthog'; - +import * as bcrypt from 'bcrypt'; import { User } from './user.model'; +import { UserCreateInput } from '../../../generated'; +import { CollectionItem } from '../collection-item/collection-item.model'; @Service('UserService') export class UserService extends BaseService { constructor(@InjectRepository(User) protected readonly repository: Repository) { super(User, repository); } + + async create(user: UserCreateInput, userId: string) { + const salt = await bcrypt.genSalt(); + user.password = await bcrypt.hash(user.password, salt); + const collection: CollectionItem[] = []; + + const payload = { + ...user, + salt, + collection, + } + + return super.create(payload, userId); + } + + // TODO: Sign in + // async validateUserPassword(authCredentialsInput: UserCreateInput): Promise { + // const { username, password } = authCredentialsInput; + // const user = await this.findOne({username}); + + // if (user && user.password === bcrypt.hash(user.password, user.salt)) { + // return user.username; + // } else { + // return 'user not found'; + // } + // } } diff --git a/yarn.lock b/yarn.lock index b3ecacb..cadfcef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -486,6 +486,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bcrypt@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-3.0.0.tgz#851489a9065a067cb7f3c9cbe4ce9bed8bba0876" + integrity sha512-nohgNyv+1ViVcubKBh0+XiNJ3dO8nYu///9aJ4cgSqv70gBL+94SNy/iC2NLzKPT2Zt/QavrOkBVbZRLZmw6NQ== + "@types/bluebird@^3.5.20": version "3.5.30" resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.30.tgz#ee034a0eeea8b84ed868b1aa60d690b08a6cfbc5" @@ -1421,6 +1426,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bcrypt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-4.0.1.tgz#06e21e749a061020e4ff1283c1faa93187ac57fe" + integrity sha512-hSIZHkUxIDS5zA2o00Kf2O5RfVbQ888n54xQoF/eIaquU4uaLxK8vhhBdktd0B3n2MjkcAWzv4mnhogykBKOUQ== + dependencies: + node-addon-api "^2.0.0" + node-pre-gyp "0.14.0" + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -2741,6 +2754,11 @@ graphql-fields@^2.0.3: resolved "https://registry.yarnpkg.com/graphql-fields/-/graphql-fields-2.0.3.tgz#5e68dff7afbb202be4f4f40623e983b22c96ab8f" integrity sha512-x3VE5lUcR4XCOxPIqaO4CE+bTK8u6gVouOdpQX9+EKHr+scqtK5Pp/l8nIGqIpN1TUlkKE6jDCCycm/WtLRAwA== +graphql-import-node@^0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/graphql-import-node/-/graphql-import-node-0.0.4.tgz#0522f058978c7e1b99d1e6be1b851ee17007b111" + integrity sha512-okpdABQIgIM0qdx9Mfgdu6fTsFEazZmHZdEU34cijkUj9D1db1SyPRGHPxbXmbacamhEF41ckxpCAgHiGliryQ== + graphql-import@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/graphql-import/-/graphql-import-0.7.1.tgz#4add8d91a5f752d764b0a4a7a461fcd93136f223" @@ -4278,6 +4296,11 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-addon-api@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.0.tgz#f9afb8d777a91525244b01775ea0ddbe1125483b" + integrity sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA== + node-emoji@^1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.10.0.tgz#8886abd25d9c7bb61802a658523d1f8d2a89b2da" @@ -4311,6 +4334,22 @@ node-notifier@^5.4.0, node-notifier@^5.4.2: shellwords "^0.1.1" which "^1.3.0" +node-pre-gyp@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz#9a0596533b877289bcad4e143982ca3d904ddc83" + integrity sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4.4.2" + node-pre-gyp@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" @@ -5821,7 +5860,7 @@ symbol-tree@^3.2.2: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== -tar@^4: +tar@^4, tar@^4.4.2: version "4.4.13" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== @@ -6205,10 +6244,10 @@ walker@^1.0.7, walker@~1.0.5: dependencies: makeerror "1.0.x" -warthog@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/warthog/-/warthog-2.1.1.tgz#61a1919099b43983169c74fca5892dcecd77ab4a" - integrity sha512-kmKtcAAZITP+O1BTGDVrV5lqPJJSMoG9W8tVGPmzSftO5polVuvLnOQBKCNqocMsvEoVKEQtrcfLVlx+he7neA== +warthog@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/warthog/-/warthog-2.6.0.tgz#cad6373a226b36a695f01a409ce345f570d11710" + integrity sha512-I0n+8+FULUqO464FVgfC8wLgqffsINWZ/4NNjBtbGG2whdn0vWOrg+FwyM+haY5jnncG3jtJ3Q4j1PrfH7xGiQ== dependencies: "@types/app-root-path" "^1.2.4" "@types/caller" "^1.0.0" @@ -6247,6 +6286,7 @@ warthog@^2.1.1: graphql "^14.5.8" graphql-binding "^2.5.2" graphql-fields "^2.0.3" + graphql-import-node "^0.0.4" graphql-iso-date "^3.6.1" graphql-tools "^4.0.6" graphql-type-json "^0.3.0"