From 37d901a86c3209378a76bed4be861b6cc81cc5e8 Mon Sep 17 00:00:00 2001 From: Baobeld Date: Wed, 11 Dec 2024 15:59:02 -0500 Subject: [PATCH] Mutation implementations (#5) * split up files * timestamps, scalars and dayjs * lib server directory * move bun types to dev * move storybook dark mode to dev * got timestamps working * fix reference * separate schema into files and add mutations --- bun.lockb | Bin 242029 -> 242377 bytes package.json | 5 +- prisma/dev.db | Bin 28672 -> 32768 bytes prisma/dev.db-journal | Bin 8720 -> 0 bytes .../migration.sql | 37 ++++++ prisma/schema.prisma | 20 ++-- src/lib/pothos/index.ts | 65 ----------- src/lib/{ => server}/config/index.ts | 2 +- src/lib/{ => server}/logger/index.ts | 0 src/lib/server/pothos/builder.ts | 28 +++++ src/lib/server/pothos/index.ts | 1 + src/lib/server/pothos/schema/Scalars/Date.ts | 14 +++ src/lib/server/pothos/schema/Scalars/index.ts | 8 ++ src/lib/server/pothos/schema/index.ts | 18 +++ src/lib/server/pothos/schema/posts.ts | 110 ++++++++++++++++++ src/lib/server/pothos/schema/users.ts | 83 +++++++++++++ src/lib/{ => server}/prisma/index.ts | 0 src/lib/{ => server}/yoga/context.ts | 2 +- src/lib/server/yoga/index.ts | 2 + .../{yoga/index.ts => server/yoga/server.ts} | 4 +- src/routes/api/graphql/+server.ts | 2 +- 21 files changed, 321 insertions(+), 80 deletions(-) delete mode 100644 prisma/dev.db-journal create mode 100644 prisma/migrations/20241211200947_add_timestamps/migration.sql delete mode 100644 src/lib/pothos/index.ts rename src/lib/{ => server}/config/index.ts (90%) rename src/lib/{ => server}/logger/index.ts (100%) create mode 100644 src/lib/server/pothos/builder.ts create mode 100644 src/lib/server/pothos/index.ts create mode 100644 src/lib/server/pothos/schema/Scalars/Date.ts create mode 100644 src/lib/server/pothos/schema/Scalars/index.ts create mode 100644 src/lib/server/pothos/schema/index.ts create mode 100644 src/lib/server/pothos/schema/posts.ts create mode 100644 src/lib/server/pothos/schema/users.ts rename src/lib/{ => server}/prisma/index.ts (100%) rename src/lib/{ => server}/yoga/context.ts (78%) create mode 100644 src/lib/server/yoga/index.ts rename src/lib/{yoga/index.ts => server/yoga/server.ts} (78%) diff --git a/bun.lockb b/bun.lockb index 37b9108af1670ffd7e70c9ae4e7c8cd7895e85c6..f9ae40a93c4a7807691bb9975c3a33a8f521f2e5 100755 GIT binary patch delta 47400 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 delta 47619 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 gQ{O|1M4^z&X7c8YPh4ddn<_F?C1Wu3 zRHl?I&CX@%e4#|=rCg4l%AU_ixe`4o&Ch4^rLrAeC}rk~BVO7%%yL8d=gX6Y{6fjx z@U^`DX+T6n*j>qMW+*9=Bi-TCAxy8-6?H{wsm*dlDKDvaY}IL&sgq+po1qJNnz6mi z5K~c@=!Tm(oIzVZoPiy&$!(VXSA9o_>!_wO=Ep#2^*=n^8!bBB;o)KIih<0Zz8NR{ z0UmWO_}}0J9_Rwt2y{Eaz7K)b^)T+0*8Q$&09+)JSuu@xF(xKCEhfZKDwY-$F2->j z%W6nt6*iTWwWJp3M3jhgNtEK`cuGtr#I&FaikeEZaXyU_yr5`;s3v$8@rsT=0y{U)ka>gNm#@#vynn>cdNMO0nVZTvfL zd%TBW55PU(v|4?J11B6~esKv1vrVq!teE_tQ;NgSKSaSV)W>JC z1efXL<6IS!zw!jJH1aUBZ}#Th$;8IUU%&icOf@r diff --git a/prisma/dev.db-journal b/prisma/dev.db-journal deleted file mode 100644 index be0024efeb2a325009d71b5f0c2fb3a1a4e8d1c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8720 zcmeI$F$w}P5CzbzAfg~zcmW%`g_+DGn|Kdv$!@Z+jg{DnXYeFe9?r(aGgt`z&(t6O zE5{h*&jlvS5ujRK%y; - -export const builder = new SchemaBuilder<{ - Context: ContextType; - PrismaTypes: PrismaTypesFromClient; -}>({ - plugins: [PrismaPlugin], - prisma: { - client: prisma, - // defaults to false, uses /// comments from prisma schema as descriptions - // for object types, relations and exposed fields. - // descriptions can be omitted by setting description to false - exposeDescriptions: false, - // use where clause from prismaRelatedConnection for totalCount (defaults to true) - filterConnectionTotalCount: true, - // warn when not using a query parameter correctly - onUnusedQuery: process.env.NODE_ENV === 'production' ? null : 'warn' - } -}); - -const User = builder.prismaObject('User', { - fields: (t) => ({ - id: t.exposeID('id'), - email: t.exposeString('email'), - name: t.exposeString('name'), - posts: t.relation('posts') - }) -}); - -const Post = builder.prismaObject('Post', { - fields: (t) => ({ - id: t.exposeID('id'), - title: t.exposeString('title'), - content: t.exposeString('content'), - published: t.exposeBoolean('published'), - author: t.relation('author') - }) -}); - -builder.queryType({ - fields: (t) => ({ - version: t.string({ - resolve: (parent, args, context) => context.config.app_version - }), - users: t.prismaField({ - type: [User], - resolve: async () => { - return await prisma.user.findMany(); - } - }), - posts: t.prismaField({ - type: [Post], - resolve: async () => { - return await prisma.post.findMany(); - } - }) - }) -}); - -export const Schema = builder.toSchema(); \ No newline at end of file diff --git a/src/lib/config/index.ts b/src/lib/server/config/index.ts similarity index 90% rename from src/lib/config/index.ts rename to src/lib/server/config/index.ts index b87d270..b7dcdbe 100644 --- a/src/lib/config/index.ts +++ b/src/lib/server/config/index.ts @@ -1,4 +1,4 @@ -import { logger } from '$lib/logger'; +import { logger } from '$lib/server/logger'; import { z } from 'zod'; export interface Configuration { diff --git a/src/lib/logger/index.ts b/src/lib/server/logger/index.ts similarity index 100% rename from src/lib/logger/index.ts rename to src/lib/server/logger/index.ts diff --git a/src/lib/server/pothos/builder.ts b/src/lib/server/pothos/builder.ts new file mode 100644 index 0000000..0b7fda4 --- /dev/null +++ b/src/lib/server/pothos/builder.ts @@ -0,0 +1,28 @@ +import { prisma } from '$lib/server/prisma'; +import type { Context } from '$lib/server/yoga'; +import SchemaBuilder from '@pothos/core'; +import PrismaPlugin, { type PrismaTypesFromClient } from '@pothos/plugin-prisma'; +import type { Scalars } from './schema/Scalars'; + +type PothosType = { + Context: ReturnType; + PrismaTypes: PrismaTypesFromClient; + Scalars: Scalars; +}; + +SchemaBuilder.allowPluginReRegistration = true; + +export const builder = new SchemaBuilder({ + plugins: [PrismaPlugin], + prisma: { + client: prisma, + // defaults to false, uses /// comments from prisma schema as descriptions + // for object types, relations and exposed fields. + // descriptions can be omitted by setting description to false + exposeDescriptions: false, + // use where clause from prismaRelatedConnection for totalCount (defaults to true) + filterConnectionTotalCount: true, + // warn when not using a query parameter correctly + onUnusedQuery: process.env.NODE_ENV === 'production' ? null : 'warn' + } +}); \ No newline at end of file diff --git a/src/lib/server/pothos/index.ts b/src/lib/server/pothos/index.ts new file mode 100644 index 0000000..5d5aa13 --- /dev/null +++ b/src/lib/server/pothos/index.ts @@ -0,0 +1 @@ +export * from './schema'; \ No newline at end of file diff --git a/src/lib/server/pothos/schema/Scalars/Date.ts b/src/lib/server/pothos/schema/Scalars/Date.ts new file mode 100644 index 0000000..6573f0a --- /dev/null +++ b/src/lib/server/pothos/schema/Scalars/Date.ts @@ -0,0 +1,14 @@ +import { builder } from '../../builder'; + +export const DateScalar = builder.scalarType('Date', { + description: 'Date Scalar in ISO format', + serialize: (date) => { + return date.toISOString(); + }, + parseValue: (date) => { + if (typeof date !== 'string') { + throw new Error('Cyka blyat'); + } + return new Date(date); + } +}); \ No newline at end of file diff --git a/src/lib/server/pothos/schema/Scalars/index.ts b/src/lib/server/pothos/schema/Scalars/index.ts new file mode 100644 index 0000000..0751f41 --- /dev/null +++ b/src/lib/server/pothos/schema/Scalars/index.ts @@ -0,0 +1,8 @@ +export * from './Date'; + +export type Scalars = { + Date: { + Input: Date; + Output: Date; + }; +}; \ No newline at end of file diff --git a/src/lib/server/pothos/schema/index.ts b/src/lib/server/pothos/schema/index.ts new file mode 100644 index 0000000..acdab44 --- /dev/null +++ b/src/lib/server/pothos/schema/index.ts @@ -0,0 +1,18 @@ +import { builder } from '../builder'; + +builder.queryType({}); + +builder.queryField('version', (t) => + t.string({ + description: 'Application version', + resolve: (parent, args, context) => context.config.app_version + }) +); + +builder.mutationType({}); + +import './Scalars'; +import './posts'; +import './users'; + +export const Schema = builder.toSchema(); \ No newline at end of file diff --git a/src/lib/server/pothos/schema/posts.ts b/src/lib/server/pothos/schema/posts.ts new file mode 100644 index 0000000..f616871 --- /dev/null +++ b/src/lib/server/pothos/schema/posts.ts @@ -0,0 +1,110 @@ +import { prisma } from '$lib/server/prisma'; +import { builder } from '../builder'; + +export const Post = builder.prismaObject('Post', { + fields: (t) => ({ + id: t.exposeID('id'), + title: t.exposeString('title'), + content: t.exposeString('content'), + published: t.exposeBoolean('published'), + author: t.relation('author'), + createdAt: t.expose('createdAt', { + type: 'Date' + }), + updatedAt: t.expose('updatedAt', { + type: 'Date' + }) + }) +}); + +const CreatePost = builder.inputType('CreatePost', { + fields: (t) => ({ + title: t.string({ + required: true + }), + content: t.string({ + required: true + }), + published: t.boolean(), + authorId: t.id({ + required: true + }) + }) +}); + +const UpdatePost = builder.inputType('UpdatePost', { + fields: (t) => ({ + id: t.id({ + required: true + }), + title: t.string(), + content: t.string(), + published: t.boolean(), + authorId: t.id() + }) +}); + +builder.queryFields((t) => ({ + posts: t.prismaField({ + type: [Post], + resolve: async () => { + return await prisma.post.findMany(); + } + }) +})); + +builder.mutationFields((t) => ({ + createPost: t.field({ + type: Post, + args: { + input: t.arg({ required: true, type: CreatePost }) + }, + resolve: async (parent, args) => { + const author = await prisma.user.findUnique({ + where: { id: Number(args.input.authorId) } + }); + if (!author) { + throw new Error('Author does not exist!'); + } + const post = await prisma.post.create({ + data: { + title: args.input.title, + content: args.input.content, + published: args.input.published, + author: { + connect: { + id: author.id + } + } + } + }); + return post; + } + }), + updatePost: t.field({ + type: Post, + args: { + input: t.arg({ required: true, type: UpdatePost }) + }, + resolve: async (parent, args) => { + const post = await prisma.post.update({ + where: { + id: Number(args.input.id) + }, + data: { + title: args.input.title ?? undefined, + content: args.input.content ?? undefined, + published: args.input.published, + ...(args.input.authorId && { + author: { + connect: { + id: Number(args.input.authorId) + } + } + }) + } + }); + return post; + } + }) +})); \ No newline at end of file diff --git a/src/lib/server/pothos/schema/users.ts b/src/lib/server/pothos/schema/users.ts new file mode 100644 index 0000000..c15b8bb --- /dev/null +++ b/src/lib/server/pothos/schema/users.ts @@ -0,0 +1,83 @@ +import { prisma } from '$lib/server/prisma'; +import { builder } from '../builder'; + +export const User = builder.prismaObject('User', { + fields: (t) => ({ + id: t.exposeID('id'), + email: t.exposeString('email'), + name: t.exposeString('name'), + posts: t.relation('posts'), + createdAt: t.expose('createdAt', { + type: 'Date' + }), + updatedAt: t.expose('updatedAt', { + type: 'Date' + }) + }) +}); + +const CreateUser = builder.inputType('CreateUser', { + fields: (t) => ({ + email: t.string({ + required: true + }), + name: t.string({ + required: true + }) + }) +}); + +const UpdateUser = builder.inputType('UpdateUser', { + fields: (t) => ({ + id: t.id({ + required: true + }), + email: t.string(), + name: t.string() + }) +}); + +builder.queryFields((t) => ({ + users: t.prismaField({ + type: [User], + resolve: async () => { + return await prisma.user.findMany(); + } + }) +})); + +builder.mutationFields((t) => ({ + createUser: t.field({ + type: User, + args: { + input: t.arg({ required: true, type: CreateUser }) + }, + resolve: async (parent, args) => { + const post = await prisma.user.create({ + data: { + email: args.input.email, + name: args.input.name + } + }); + return post; + } + }), + updateUser: t.field({ + type: User, + args: { + input: t.arg({ required: true, type: UpdateUser }) + }, + resolve: async (parent, args) => { + const post = await prisma.user.update({ + where: { + id: Number(args.input.id) + }, + data: { + email: args.input.email, + name: args.input.name ?? undefined + } + }); + return post; + } + }) +})); \ No newline at end of file diff --git a/src/lib/prisma/index.ts b/src/lib/server/prisma/index.ts similarity index 100% rename from src/lib/prisma/index.ts rename to src/lib/server/prisma/index.ts diff --git a/src/lib/yoga/context.ts b/src/lib/server/yoga/context.ts similarity index 78% rename from src/lib/yoga/context.ts rename to src/lib/server/yoga/context.ts index d9a6a68..8a3ab51 100644 --- a/src/lib/yoga/context.ts +++ b/src/lib/server/yoga/context.ts @@ -1,4 +1,4 @@ -import { Config } from '$lib/config'; +import { Config } from '$lib/server/config'; import type { YogaInitialContext } from 'graphql-yoga'; export const Context = (initialContext: YogaInitialContext) => ({ diff --git a/src/lib/server/yoga/index.ts b/src/lib/server/yoga/index.ts new file mode 100644 index 0000000..b489ffb --- /dev/null +++ b/src/lib/server/yoga/index.ts @@ -0,0 +1,2 @@ +export * from './context'; +export * from './server'; \ No newline at end of file diff --git a/src/lib/yoga/index.ts b/src/lib/server/yoga/server.ts similarity index 78% rename from src/lib/yoga/index.ts rename to src/lib/server/yoga/server.ts index b008b24..4bdfbe6 100644 --- a/src/lib/yoga/index.ts +++ b/src/lib/server/yoga/server.ts @@ -1,5 +1,5 @@ -import { yogaLogger } from '$lib/logger'; -import { Schema } from '$lib/pothos'; +import { yogaLogger } from '$lib/server/logger'; +import { Schema } from '$lib/server/pothos'; import type { RequestEvent } from '@sveltejs/kit'; import { createYoga } from 'graphql-yoga'; import { Context } from './context'; diff --git a/src/routes/api/graphql/+server.ts b/src/routes/api/graphql/+server.ts index 72aab8c..c208143 100644 --- a/src/routes/api/graphql/+server.ts +++ b/src/routes/api/graphql/+server.ts @@ -1,3 +1,3 @@ -import { Yoga } from '$lib/yoga'; +import { Yoga } from '$lib/server/yoga'; export { Yoga as GET, Yoga as POST }; \ No newline at end of file