Search code examples
postgresqlgraphqlprisma

How to query a date/time field using pothos with prisma and postgresql


I've got my pothos set up using Prisma and postgresql. I'm trying to expose the createdAt and updatedAt fields from prisma in my builder:

Prisma schema:

model Course {
  id          Int      @id @unique @default(autoincrement())
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt
  // removed fields for brevity. 
}

My builder:

builder.prismaObject('Course', {
  fields: (t) => ({
    id: t.exposeID('id'),
    createdAt: t.expose('createdAt', {
      type: 'DateTime' as any,
    })
  })
})

I have also tried this way:

builder.prismaObject('Course', {
      fields: (t) => ({
        id: t.exposeID('id'),
        createdAt: t.expose('createdAt', {
          type: Date, // simply set this as a Date type
        })
      })
    })

These two ways causes the same/similar error:

- error node_modules/@pothos/core/esm/config-store.js (210:18) @ ConfigStore.onTypeConfig
- error Error [PothosSchemaError]: Ref DateTime has not been implemented

I've also tried this which works, but obviously hacky (I don't want to leave it this way):

// @ts-ignore
    createdAt: t.exposeString('createdAt', {
      type: Date
    })

Solution

  • Figured it out. The fix is a bit long, but I had to add the following library:

    npm i graphql-scalars
    

    Builder.ts this may be very case specific, but this is how I set it up:

    import { DateTimeResolver} from "graphql-scalars";
    // ... other code you may have here
    
    export const builder = new SchemaBuilder<{
      PrismaTypes: PrismaTypes,
      Context: ReturnType<typeof createContext>, // add the scalar type below
      Scalars: {
        Date: {
          Input: Date;
          Output: Date;
        };
      };
    }>({
      plugins: [PrismaPlugin, RelayPlugin, WithInputPlugin],
      relayOptions: {},
      prisma: {
        client: prisma,
      }
    })
    
    ... other code
    builder.queryType({
    
    
    fields: (t) => ({
        ok: t.boolean({
          resolve: () => true,
        }),
      }),
    });
    
    // define your scalar type using the DateTimeResolver
    
    builder.addScalarType("Date", DateTimeResolver, {});
    

    Now you create your prisma object in whatever file you're adding the Date type field:

    builder.prismaObject('Course', {
      fields: (t) => ({
        id: t.exposeID('id'),
        ...
        Lesson: t.relation('lessons'),
        createdAt: t.expose('createdAt', { // use the Date scalary type you defined here...
          type: 'Date',
        }),
        updatedAt: t.expose('updatedAt', {
          type: 'Date',
        })
      })