From ac1d1cb35f114869f94b0c9ce06dcd22707c1917 Mon Sep 17 00:00:00 2001 From: Daniel Cousens <413395+dcousens@users.noreply.github.com> Date: Thu, 31 Aug 2023 21:37:40 +1000 Subject: [PATCH] Use type guards for better type refinement in examples/usecase-blog-moderated (#8796) --- examples/auth/schema.ts | 2 +- examples/usecase-blog-moderated/schema.ts | 46 +++++++++++++++-------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/examples/auth/schema.ts b/examples/auth/schema.ts index 664c4c50545..95be69e99ea 100644 --- a/examples/auth/schema.ts +++ b/examples/auth/schema.ts @@ -55,7 +55,7 @@ function isAdmin({ session }: { session?: Session }) { return false; } -export const lists: Lists = { +export const lists: Lists = { User: list({ access: { operation: { diff --git a/examples/usecase-blog-moderated/schema.ts b/examples/usecase-blog-moderated/schema.ts index 3eee7303bf4..cad6ea6c12a 100644 --- a/examples/usecase-blog-moderated/schema.ts +++ b/examples/usecase-blog-moderated/schema.ts @@ -10,26 +10,40 @@ import type { Lists } from '.keystone/types'; export type Session = { id: string; admin: boolean; - contributor: null | { id: string }; moderator: null | { id: string }; + contributor: null | { id: string }; +}; + +type Has = { + [key in keyof T]: key extends K ? Exclude : T[key]; }; +function isAdmin(session?: T): session is T & { admin: true } { + return session?.admin === true; +} +function isModerator(session?: T): session is Has { + return session?.moderator !== null; +} +function isContributor(session?: T): session is Has { + return session?.contributor !== null; +} + function forUsers({ admin, moderator, contributor, default: _default, }: { - admin?: ({ session }: { session: Session }) => T; - moderator?: ({ session }: { session: Session }) => T; - contributor?: ({ session }: { session: Session }) => T; + admin?: ({ session }: { session: Session & { admin: true } }) => T; + moderator?: ({ session }: { session: Has }) => T; + contributor?: ({ session }: { session: Has }) => T; default: () => T; }) { return ({ session }: { session?: Session }): T => { if (!session) return _default(); - if (admin && session.admin) return admin({ session }); - if (moderator && session.moderator) return moderator({ session }); - if (contributor && session.contributor) return contributor({ session }); + if (admin && isAdmin(session)) return admin({ session }); + if (moderator && isModerator(session)) return moderator({ session }); + if (contributor && isContributor(session)) return contributor({ session }); return _default(); }; } @@ -109,7 +123,7 @@ export const lists: Lists = { update: forUsers({ // contributors can only update their own posts contributor: ({ session }) => ({ - createdBy: { id: { equals: session.contributor?.id } }, + createdBy: { id: { equals: session.contributor.id } }, hiddenBy: null, }), // otherwise, no filter @@ -163,27 +177,27 @@ export const lists: Lists = { }, hooks: { resolveInput: { - create: ({ context, resolvedData }) => { + create: ({ context: { session }, resolvedData }) => { resolvedData.createdAt = new Date(); - if (context.session?.contributor) { + if (isContributor(session)) { return { ...resolvedData, createdBy: { connect: { - id: context.session?.contributor?.id, + id: session.contributor.id, }, }, }; } return resolvedData; }, - update: ({ context, resolvedData }) => { + update: ({ context: { session }, resolvedData }) => { resolvedData.updatedAt = new Date(); - if ('hidden' in resolvedData && context.session?.moderator) { + if ('hidden' in resolvedData && isModerator(session)) { resolvedData.hiddenBy = resolvedData.hidden ? { connect: { - id: context.session?.moderator?.id, + id: session.moderator.id, }, // TODO: should support : null } @@ -211,7 +225,7 @@ export const lists: Lists = { filter: { // contributors can only update themselves update: forUsers({ - contributor: ({ session }) => ({ id: { equals: session.contributor?.id } }), + contributor: ({ session }) => ({ id: { equals: session.contributor.id } }), default: unfiltered, }), }, @@ -237,7 +251,7 @@ export const lists: Lists = { filter: { // moderators can only update themselves update: forUsers({ - moderator: ({ session }) => ({ id: { equals: session.moderator?.id } }), + moderator: ({ session }) => ({ id: { equals: session.moderator.id } }), // otherwise, no filter default: unfiltered, }),