Mutation implementations #5

Merged
BenjaminPalko merged 8 commits from mutation-examples into master 2024-12-11 15:59:02 -05:00
12 changed files with 258 additions and 63 deletions
Showing only changes of commit 2e1d0b2b5e - Show all commits

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,37 @@
/*
Warnings:
- Made the column `content` on table `Post` required. This step will fail if there are existing NULL values in that column.
- Made the column `name` on table `User` required. This step will fail if there are existing NULL values in that column.
*/
-- RedefineTables
PRAGMA defer_foreign_keys=ON;
PRAGMA foreign_keys=OFF;
CREATE TABLE "new_Post" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"published" BOOLEAN DEFAULT false,
"authorId" INTEGER NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
INSERT INTO "new_Post" ("authorId", "content", "id", "published", "title") SELECT "authorId", "content", "id", "published", "title" FROM "Post";
DROP TABLE "Post";
ALTER TABLE "new_Post" RENAME TO "Post";
CREATE TABLE "new_User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"email" TEXT,
"name" TEXT NOT NULL,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
INSERT INTO "new_User" ("email", "id", "name") SELECT "email", "id", "name" FROM "User";
DROP TABLE "User";
ALTER TABLE "new_User" RENAME TO "User";
CREATE UNIQUE INDEX "User_id_key" ON "User"("id");
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
PRAGMA foreign_keys=ON;
PRAGMA defer_foreign_keys=OFF;

View file

@ -15,9 +15,9 @@ datasource db {
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
id Int @id @default(autoincrement()) @unique
email String? @unique
name String
posts Post[]
createdAt DateTime @default(now())
updatedAt DateTime @default(now()) @updatedAt
@ -26,8 +26,8 @@ model User {
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
content String
published Boolean? @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
createdAt DateTime @default(now())

View file

@ -2,7 +2,7 @@ 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 './Scalars';
import type { Scalars } from './schema/Scalars';
type PothosType = {
Context: ReturnType<typeof Context>;
@ -10,6 +10,8 @@ type PothosType = {
Scalars: Scalars;
};
SchemaBuilder.allowPluginReRegistration = true;
export const builder = new SchemaBuilder<PothosType>({
plugins: [PrismaPlugin],
prisma: {

View file

@ -1,3 +1 @@
import { builder } from './builder';
export const Schema = builder.toSchema();
export * from './schema';

View file

@ -1,53 +0,0 @@
import { prisma } from '$lib/server/prisma';
import { builder } from './builder';
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 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'
})
})
});
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();
}
})
})
});

View file

@ -1,4 +1,4 @@
import { builder } from '../builder';
import { builder } from '../../builder';
export const DateScalar = builder.scalarType('Date', {
description: 'Date Scalar in ISO format',

View file

@ -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();

View file

@ -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;
}
})
}));

View file

@ -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;
}
})
}));