(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[2118],{8214:function(s,e,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/docs/plugins/prisma",function(){return n(6458)}])},6458:function(s,e,n){"use strict";n.r(e),n.d(e,{__N_SSG:function(){return t},frontmatter:function(){return c}});var a=n(5250),l=n(7160),i=n(3210),t=!0;let c={name:"Prisma plugin",title:"Prisma plugin for Pothos GraphQL",menu:"Plugins",description:"Prisma plugin docs for Pothos"},r=i.k;function h(s){let e=Object.assign({h1:"h1",p:"p",a:"a",h2:"h2",ul:"ul",li:"li",pre:"pre",code:"code",span:"span",h3:"h3",ol:"ol",em:"em",h4:"h4"},(0,l.ah)(),s.components);return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(e.h1,{id:"prisma-plugin-for-pothos",children:"Prisma Plugin for Pothos"}),"\n",(0,a.jsx)(e.p,{children:"This plugin provides tighter integration with prisma, making it easier to define prisma based object\ntypes, and helps solve n+1 queries for relations. It also has integrations for the relay plugin to\nmake defining nodes and connections easy and efficient."}),"\n",(0,a.jsxs)(e.p,{children:["This plugin is NOT required to use prisma with Pothos, but does make things a lot easier and more\nefficient. See the ",(0,a.jsx)(e.a,{href:"#using-prisma-without-a-plugin",children:"Using Prisma without a plugin"})," section below for\nmore details."]}),"\n",(0,a.jsx)(e.h2,{id:"features",children:"Features"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsx)(e.li,{children:"\uD83C\uDFA8 Quickly define GraphQL types based on your Prisma models"}),"\n",(0,a.jsx)(e.li,{children:"\uD83E\uDDBA Strong type-safety throughout the entire API"}),"\n",(0,a.jsx)(e.li,{children:"\uD83E\uDD1D Automatically resolve relationships defined in your database"}),"\n",(0,a.jsx)(e.li,{children:"\uD83C\uDFA3 Automatic Query optimization to efficiently load the specific data needed to resolve a query\n(solves common N+1 issues)"}),"\n",(0,a.jsx)(e.li,{children:"\uD83D\uDC85 Types and fields in GraphQL schema are not implicitly tied to the column names or types in your\ndatabase."}),"\n",(0,a.jsx)(e.li,{children:"\uD83D\uDD00 Relay integration for defining nodes and connections that can be efficiently loaded."}),"\n",(0,a.jsx)(e.li,{children:"\uD83D\uDCDA Supports multiple GraphQL models based on the same Database model"}),"\n",(0,a.jsx)(e.li,{children:"\uD83E\uDDEE Count fields can easily be added to objects and connections"}),"\n"]}),"\n",(0,a.jsx)(e.h2,{id:"example",children:"Example"}),"\n",(0,a.jsx)(e.p,{children:"Here is a quick example of what an API using this plugin might look like. There is a more thorough\nbreakdown of what the methods and options used in the example below."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Create an object type based on a prisma model"}),"\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// without providing any custom type information"}),"\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// expose fields from the database"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"bio"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"string"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// automatically load the bio from the profile"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// when this field is queried"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"profile"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"bio"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n          },\n        },\n      },\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// user will be typed correctly to include the"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// selected fields from above"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"profile"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"bio"}),",\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Load posts as list field."}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"args"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"oldestFirst"}),": t.",(0,a.jsx)(e.span,{className:"hljs-property",children:"arg"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"boolean"}),"(),\n      },\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Define custom query options that are applied when"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// loading the post relation"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"query"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, context"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"orderBy"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": args.",(0,a.jsx)(e.span,{className:"hljs-property",children:"oldestFirst"})," ? ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'asc'"})," : ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'desc'"}),",\n        },\n      }),\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// creates relay connection that handles pagination"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// using prisma's built in cursor based pagination"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"postsConnection"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relatedConnection"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n    }),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Create a relay node based a prisma model"}),"\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"field"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"})," },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"queryType"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Define a field that issues an optimized prisma query"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"me"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaField"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"async"})," (query, root, args, ctx, info) =>\n        prisma.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findUniqueOrThrow"}),"({\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// the `query` argument will add in `include`s or `select`s to"}),"\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// resolve as much of the request in a single query as possible"}),"\n          ...query,\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ctx.",(0,a.jsx)(e.span,{className:"hljs-property",children:"userId"})," },\n        }),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.p,{children:"Given this schema, you would be able to resolve a query like the following with a single prisma\nquery (which will still result in a few optimized SQL queries)."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-graphql",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"query"})," {\n  me {\n    email\n    posts {\n      title\n      author {\n        id\n      }\n    }\n  }\n}\n"]})}),"\n",(0,a.jsx)(e.p,{children:"A query like"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-graphql",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"query"})," {\n  me {\n    email\n    posts {\n      title\n      author {\n        id\n      }\n    }\n    oldPosts: posts(oldestFirst: ",(0,a.jsx)(e.span,{className:"hljs-variable",children:"true"}),") {\n      title\n      author {\n        id\n      }\n    }\n  }\n}\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["Will result in 2 calls to prisma, one to resolve everything except ",(0,a.jsx)(e.code,{children:"oldPosts"}),", and a second to\nresolve everything inside ",(0,a.jsx)(e.code,{children:"oldPosts"}),". Prisma can only resolve each relation once in a single query,\nso we need a separate to handle the second ",(0,a.jsx)(e.code,{children:"posts"})," relation."]}),"\n",(0,a.jsx)(e.h2,{id:"install",children:"Install"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"hljs language-bash",children:"yarn add @pothos/plugin-prisma\n"})}),"\n",(0,a.jsx)(e.h2,{id:"setup",children:"Setup"}),"\n",(0,a.jsx)(e.p,{children:"This plugin requires a little more setup than other plugins because it integrates with the prisma to\ngenerate some types that help the plugin better understand your prisma schema. Previous versions of\nthis plugin used to infer all required types from the prisma client itself, but this resulted in a\npoor dev experience because the complex types slowed down editors, and some more advanced use cases\ncould not be typed correctly."}),"\n",(0,a.jsxs)(e.h3,{id:"add-a-the-pothos-generator-to-your-prisma-schema",children:["Add a the ",(0,a.jsx)(e.code,{children:"pothos"})," generator to your prisma schema"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:'generator pothos {\n  provider = "prisma-pothos-types"\n}\n'})}),"\n",(0,a.jsx)(e.p,{children:"Now the types Pothos uses will be generated whenever you re-generate your prisma client. Run the\nfollowing command to re-generate the client and create the new types:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{className:"hljs language-sh",children:"npx prisma generate\n"})}),"\n",(0,a.jsx)(e.p,{children:"additional options:"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"clientOutput"}),": Where the generated code will import the PrismaClient from. The default is the\nfull path of wherever the client is generated. If you are checking in the generated file, using\n",(0,a.jsx)(e.code,{children:"@prisma/client"})," is a good option."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"output"}),": Where to write the generated types"]}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"Example with more options:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:'generator pothos {\n  provider = "prisma-pothos-types"\n  clientOutput = "@prisma/client"\n  output = "./pothos-types.ts"\n}\n'})}),"\n",(0,a.jsx)(e.h3,{id:"set-up-the-builder",children:"Set up the builder"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"SchemaBuilder"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@pothos/core'"}),";\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," { ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"})," } ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@prisma/client'"}),";\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaPlugin"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@pothos/plugin-prisma'"}),";\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This is the default location for the generator, but this can be"}),"\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// customized as described above."}),"\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Using a type only import will help avoid issues with undeclared"}),"\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// exports in esm mode"}),"\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"type"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaTypes"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@pothos/plugin-prisma/generated'"}),";\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," prisma = ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"new"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"}),"({});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," builder = ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"new"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"SchemaBuilder"}),"<{\n  ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaTypes"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaTypes"}),";\n}>({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"plugins"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaPlugin"}),"],\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"prisma"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"client"}),": prisma,\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// defaults to false, uses /// comments from prisma schema as descriptions"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// for object types, relations and exposed fields."}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// descriptions can be omitted by setting description to false"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"exposeDescriptions"}),": ",(0,a.jsx)(e.span,{className:"hljs-built_in",children:"boolean"})," | { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"models"}),": ",(0,a.jsx)(e.span,{className:"hljs-built_in",children:"boolean"}),", ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsx)(e.span,{className:"hljs-built_in",children:"boolean"})," },\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// use where clause from prismaRelatedConnection for totalCount (will true by default in next major version)"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"filterConnectionTotalCount"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// warn when not using a query parameter correctly"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"onUnusedQuery"}),": process.",(0,a.jsx)(e.span,{className:"hljs-property",children:"env"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"NODE_ENV"})," === ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'production'"})," ? ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"null"})," : ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'warn'"}),",\n  },\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["It is strongly recommended NOT to put your prisma client into ",(0,a.jsx)(e.code,{children:"Context"}),". This will result in slower\ntype-checking and a laggy developer experience in VSCode. See\n",(0,a.jsx)(e.a,{href:"https://github.com/microsoft/TypeScript/issues/45405",children:"this issue"})," for more details."]}),"\n",(0,a.jsx)(e.p,{children:"You can also load or create the prisma client dynamically for each request. This can be used to\nperiodically re-create clients or create read-only clients for certain types of users."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"SchemaBuilder"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@pothos/core'"}),";\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," { ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"}),", ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Prisma"})," } ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@prisma/client'"}),";\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaPlugin"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@pothos/plugin-prisma'"}),";\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"type"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaTypes"})," ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@pothos/plugin-prisma/generated'"}),";\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," prisma = ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"new"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"}),"({});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," readOnlyPrisma = ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"new"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"datasources"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"db"}),": {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"url"}),": process.",(0,a.jsx)(e.span,{className:"hljs-property",children:"env"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"READ_ONLY_REPLICA_URL"}),",\n    },\n  },\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," builder = ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"new"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"SchemaBuilder"}),"<{\n  ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Context"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"user"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"isAdmin"}),": ",(0,a.jsx)(e.span,{className:"hljs-built_in",children:"boolean"})," } };\n  ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaTypes"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaTypes"}),";\n}>({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"plugins"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaPlugin"}),"],\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"prisma"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"client"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"ctx"}),") =>"]})," (ctx.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"isAdmin"})," ? prisma : readOnlyPrisma),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Because the prisma client is loaded dynamically, we need to explicitly provide the some information about the prisma schema"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"dmmf"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Prisma"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"dmmf"}),",\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// use where clause from prismaRelatedConnection for totalCount (will true by default in next major version)"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"filterConnectionTotalCount"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  },\n});\n"]})}),"\n",(0,a.jsxs)(e.h2,{id:"creating-types-with-builderprismaobject",children:["Creating types with ",(0,a.jsx)(e.code,{children:"builder.prismaObject"})]}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.code,{children:"builder.prismaObject"})," takes 2 arguments:"]}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"name"}),": The name of the prisma model this new type represents"]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"options"}),": options for the type being created, this is very similar to the options for any other\nobject type"]}),"\n"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Optional name for the object, defaults to the name of the prisma model"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"name"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'PostAuthor'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.p,{children:"So far, this is just creating some simple object types. They work just like any other object type in\nPothos. The main advantage of this is that we get the type information without using object refs, or\nneeding imports from prisma client."}),"\n",(0,a.jsx)(e.h2,{id:"adding-prisma-fields-to-non-prisma-objects-including-query-and-mutation",children:"Adding prisma fields to non-prisma objects (including Query and Mutation)"}),"\n",(0,a.jsxs)(e.p,{children:["There is a new ",(0,a.jsx)(e.code,{children:"t.prismaField"})," method which can be used to define fields that resolve to your prisma\ntypes:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"queryType"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"me"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaField"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"async"})," (query, root, args, ctx, info) =>\n        prisma.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findUniqueOrThrow"}),"({\n          ...query,\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ctx.",(0,a.jsx)(e.span,{className:"hljs-property",children:"userId"})," },\n        }),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["This method works just like the normal ",(0,a.jsx)(e.code,{children:"t.field"})," method with a couple of differences:"]}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["The ",(0,a.jsx)(e.code,{children:"type"})," option must contain the name of the prisma model (eg. ",(0,a.jsx)(e.code,{children:"User"})," or ",(0,a.jsx)(e.code,{children:"[User]"})," for a list\nfield)."]}),"\n",(0,a.jsxs)(e.li,{children:["The ",(0,a.jsx)(e.code,{children:"resolve"})," function has a new first argument ",(0,a.jsx)(e.code,{children:"query"})," which should be spread into query prisma\nquery. This will be used to load data for nested relationships."]}),"\n"]}),"\n",(0,a.jsxs)(e.p,{children:["You do not need to use this method, and the ",(0,a.jsx)(e.code,{children:"builder.prismaObject"})," method returns an object ref than\ncan be used like any other object ref (with ",(0,a.jsx)(e.code,{children:"t.field"}),"), but using ",(0,a.jsx)(e.code,{children:"t.prismaField"})," will allow you to\ntake advantage of more efficient queries."]}),"\n",(0,a.jsxs)(e.p,{children:["The ",(0,a.jsx)(e.code,{children:"query"})," object will contain an object with ",(0,a.jsx)(e.code,{children:"include"})," or ",(0,a.jsx)(e.code,{children:"select"})," options to pre-load data needed\nto resolve nested parts of the current query. The included/selected fields are based on which fields\nare being queried, and the options provided when defining those fields and types."]}),"\n",(0,a.jsx)(e.h2,{id:"adding-relations",children:"Adding relations"}),"\n",(0,a.jsxs)(e.p,{children:["You can add fields for relations using the ",(0,a.jsx)(e.code,{children:"t.relation"})," method:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"queryType"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"me"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaField"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"async"})," (query, root, args, ctx, info) =>\n        prisma.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findUniqueOrThrow"}),"({\n          ...query,\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ctx.",(0,a.jsx)(e.span,{className:"hljs-property",children:"userId"})," },\n        }),\n    }),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),"),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.code,{children:"t.relation"})," defines a field that can be pre-loaded by a parent resolver. This will create something\nlike ",(0,a.jsx)(e.code,{children:"{ include: { author: true }}"})," that will be passed as part of the ",(0,a.jsx)(e.code,{children:"query"})," argument of a\n",(0,a.jsx)(e.code,{children:"prismaField"})," resolver. If the parent is another ",(0,a.jsx)(e.code,{children:"relation"})," field, the includes will become nested,\nand the full relation chain will be passed to the ",(0,a.jsx)(e.code,{children:"prismaField"})," that started the chain."]}),"\n",(0,a.jsx)(e.p,{children:"For example the query:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-graphql",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"query"})," {\n  me {\n    posts {\n      author {\n        id\n      }\n    }\n  }\n}\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["the ",(0,a.jsx)(e.code,{children:"me"})," ",(0,a.jsx)(e.code,{children:"prismaField"})," would receive something like the following as its query parameter:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["{\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"include"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"include"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),";\n      }\n    }\n  }\n}\n"]})}),"\n",(0,a.jsx)(e.p,{children:"This will work perfectly for the majority of queries. There are a number of edge cases that make it\nimpossible to resolve everything in a single query. When this happens Pothos will automatically\nconstruct an additional query to ensure that everything is still loaded correctly, and split into as\nfew efficient queries as possible. This process is described in more detail below"}),"\n",(0,a.jsx)(e.h3,{id:"fallback-queries",children:"Fallback queries"}),"\n",(0,a.jsxs)(e.p,{children:["There are some cases where data can not be pre-loaded by a prisma field. In these cases, pothos will\nissue a ",(0,a.jsx)(e.code,{children:"findUnique"})," query for the parent of any fields that were not pre-loaded, and select the\nmissing relations so those fields can be resolved with the correct data. These queries should be\nvery efficient, are batched by pothos to combine requirements for multiple fields into one query,\nand batched by Prisma to combine multiple queries (in an n+1 situation) to a single sql query."]}),"\n",(0,a.jsx)(e.p,{children:"The following are some edge cases that could cause an additional query to be necessary:"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsxs)(e.li,{children:["The parent object was not loaded through a field defined with ",(0,a.jsx)(e.code,{children:"t.prismaField"}),", or ",(0,a.jsx)(e.code,{children:"t.relation"})]}),"\n",(0,a.jsxs)(e.li,{children:["The root ",(0,a.jsx)(e.code,{children:"prismaField"})," did not correctly spread the ",(0,a.jsx)(e.code,{children:"query"})," arguments in is prisma call."]}),"\n",(0,a.jsx)(e.li,{children:"The query selects multiple fields that use the same relation with different filters, sorting, or\nlimits"}),"\n",(0,a.jsx)(e.li,{children:"The query contains multiple aliases for the same relation field with different arguments in a way\nthat results in different query options for the relation."}),"\n",(0,a.jsx)(e.li,{children:"A relation field has a query that is incompatible with the default includes of the parent object"}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"All of the above should be relatively uncommon in normal usage, but the plugin ensures that these\ntypes of edge cases are automatically handled when they do occur."}),"\n",(0,a.jsx)(e.h3,{id:"filters-sorting-and-arguments",children:"Filters, Sorting, and arguments"}),"\n",(0,a.jsxs)(e.p,{children:["So far we have been describing very simple queries without any arguments, filtering, or sorting. For\n",(0,a.jsx)(e.code,{children:"t.prismaField"})," definitions, you can add arguments to your field like normal, and pass them into\nyour prisma query as needed. For ",(0,a.jsx)(e.code,{children:"t.relation"})," the flow is slightly different because we are not\nmaking a prisma query directly. We do this by adding a ",(0,a.jsx)(e.code,{children:"query"})," option to our field options. Query\ncan either be a query object, or a method that returns a query object based on the field arguments."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// We can define arguments like any other field"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"args"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"oldestFirst"}),": t.",(0,a.jsx)(e.span,{className:"hljs-property",children:"arg"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"boolean"}),"(),\n      },\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Then we can generate our query conditions based on the arguments"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"query"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, context"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"orderBy"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": args.",(0,a.jsx)(e.span,{className:"hljs-property",children:"oldestFirst"})," ? ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'asc'"})," : ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'desc'"}),",\n        },\n      }),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["The returned query object will be added to the include section of the ",(0,a.jsx)(e.code,{children:"query"})," argument that gets\npassed into the first argument of the parent ",(0,a.jsx)(e.code,{children:"t.prismaField"}),", and can include things like ",(0,a.jsx)(e.code,{children:"where"}),",\n",(0,a.jsx)(e.code,{children:"skip"}),", ",(0,a.jsx)(e.code,{children:"take"}),", and ",(0,a.jsx)(e.code,{children:"orderBy"}),". The ",(0,a.jsx)(e.code,{children:"query"})," function will be passed the arguments for the field, and\nthe context for the current request. Because it is used for pre-loading data, and solving n+1\nissues, it can not be passed the ",(0,a.jsx)(e.code,{children:"parent"})," object because it may not be loaded yet."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// We can define arguments like any other field"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"args"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"oldestFirst"}),": t.",(0,a.jsx)(e.span,{className:"hljs-property",children:"arg"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"boolean"}),"(),\n      },\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Then we can generate our query conditions based on the arguments"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"query"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, context"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"orderBy"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": args.",(0,a.jsx)(e.span,{className:"hljs-property",children:"oldestFirst"})," ? ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'asc'"})," : ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'desc'"}),",\n        },\n      }),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"relationcount",children:"relationCount"}),"\n",(0,a.jsxs)(e.p,{children:["Prisma supports querying for\n",(0,a.jsx)(e.a,{href:"https://www.prisma.io/docs/concepts/components/prisma-client/aggregation-grouping-summarizing#count-relations",children:"relation counts"}),"\nwhich allow including counts for relations along side other ",(0,a.jsx)(e.code,{children:"includes"}),". Before prisma 4.2.0, this\ndoes not support any filters on the counts, but can give a total count for a relation. Starting from\nprisma 4.2.0, filters on relation count are available under the ",(0,a.jsx)(e.code,{children:"filteredRelationCount"})," preview\nfeature flag."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"postCount"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relationCount"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"published"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n      },\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"includes-on-types",children:"Includes on types"}),"\n",(0,a.jsx)(e.p,{children:"In some cases, you may want to always pre-load certain relations. This can be helpful for defining\nfields directly on type where the underlying data may come from a related table."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This will always include the profile when a user object is loaded.  Deeply nested relations can"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// also be included this way."}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"include"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"profile"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"bio"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"string"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// The profile relation will always be loaded, and user will now be typed to include the"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// profile field so you can return the bio from the nested profile relation."}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"profile"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"bio"}),",\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"select-mode-for-types",children:"Select mode for types"}),"\n",(0,a.jsxs)(e.p,{children:["By default, the prisma plugin will use ",(0,a.jsx)(e.code,{children:"include"})," when including relations, or generating fallback\nqueries. This means we are always loading all columns of a table when loading it in a\n",(0,a.jsx)(e.code,{children:"t.prismaField"})," or a ",(0,a.jsx)(e.code,{children:"t.relation"}),". This is usually what we want, but in some cases, you may want to\nselect specific columns instead. This can be useful if you have tables with either a very large\nnumber of columns, or specific columns with large payloads you want to avoid loading."]}),"\n",(0,a.jsxs)(e.p,{children:["To do this, you can add a ",(0,a.jsx)(e.code,{children:"select"})," instead of an include to your ",(0,a.jsx)(e.code,{children:"prismaObject"}),":"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["The ",(0,a.jsx)(e.code,{children:"t.expose*"})," and ",(0,a.jsx)(e.code,{children:"t.relation"})," methods will all automatically add selections for the exposed\nfields ",(0,a.jsx)(e.em,{children:"WHEN THEY ARE QUERIED"}),", ensuring that only the requested columns will be loaded from the\ndatabase."]}),"\n",(0,a.jsxs)(e.p,{children:["In addition to the ",(0,a.jsx)(e.code,{children:"t.expose"})," and ",(0,a.jsx)(e.code,{children:"t.relation"}),", you can also add custom selections to other fields:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"bio"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"string"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This will select user.profile.bio when the the `bio` field is queried"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"profile"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"bio"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n          },\n        },\n      },\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"profile"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"bio"}),",\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"using-arguments-or-context-in-your-selections",children:"Using arguments or context in your selections"}),"\n",(0,a.jsx)(e.p,{children:"The following is a slightly contrived example, but shows how arguments can be used when creating a\nselection for a field:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostDraft"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"commentFromDate"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"string"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"args"}),": {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"date"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"arg"}),"({ ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Date'"}),", ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"required"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"})," }),\n      },\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"comments"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"take"}),": ",(0,a.jsx)(e.span,{className:"hljs-number",children:"1"}),",\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": {\n              ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"gt"}),": args.",(0,a.jsx)(e.span,{className:"hljs-property",children:"date"}),",\n            },\n          },\n        },\n      }),\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"comments"}),"[",(0,a.jsx)(e.span,{className:"hljs-number",children:"0"}),"]?.",(0,a.jsx)(e.span,{className:"hljs-property",children:"content"}),",\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"extending-prisma-objects",children:"Extending prisma objects"}),"\n",(0,a.jsxs)(e.p,{children:["The normal ",(0,a.jsx)(e.code,{children:"builder.objectField(s)"})," methods can be used to extend prisma objects, but do not support\nusing selections, or exposing fields not in the default selection. To use these features, you can\nuse"]}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.code,{children:"builder.prismaObjectField"})," or ",(0,a.jsx)(e.code,{children:"builder.prismaObjectFields"})," instead."]}),"\n",(0,a.jsx)(e.h2,{id:"type-variants",children:"Type variants"}),"\n",(0,a.jsxs)(e.p,{children:["The prisma plugin supports defining multiple GraphQL types based on the same prisma model.\nAdditional types are called ",(0,a.jsx)(e.code,{children:"variants"}),'. You will always need to have a "Primary" variant (defined as\ndescribed above). Additional variants can be defined by providing a ',(0,a.jsx)(e.code,{children:"variant"})," option instead of a\n",(0,a.jsx)(e.code,{children:"name"})," option when creating the type:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Viewer"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Viewer'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n  });\n});\n"]})}),"\n",(0,a.jsx)(e.p,{children:"You can define variant fields that reference one variant from another:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Viewer"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Viewer'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Using the model name ('User') will reference the primary variant"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"user"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"variant"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),"),\n  });\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// To reference another variant, use the returned object Ref instead of the model name:"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"viewer"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"variant"}),"(",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Viewer"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// return null for viewer if the parent User is not the current user"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"isNull"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user, args, ctx"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"})," !== ctx.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"}),",\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["You can also use variants when defining relations by providing a ",(0,a.jsx)(e.code,{children:"type"})," option:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostDraft"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'PostDraft'"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This set's what database field to use for the nodes id field"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"field"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"})," },\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// fields work just like they do for builder.prismaObject"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Viewer"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Viewer'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"drafts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This will cause this relation to use the PostDraft variant rather than the default Post variant"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostDraft"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"query"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"draft"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"})," } },\n    }),\n  });\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["You may run into circular reference issues if you use 2 prisma object refs to reference each other.\nTo avoid this, you can split out the field definition for one of the relationships using\n",(0,a.jsx)(e.code,{children:"builder.prismaObjectField"})]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Viewer"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Viewer'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"user"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"variant"}),"(",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"}),"),\n  });\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"interfaces"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Named"}),"],\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Viewer references the `User` ref in its field definition,"}),"\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// referencing the `User` in fields would cause a circular type issue"}),"\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObjectField"}),"(",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Viewer"}),", ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'user'"}),", t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"variant"}),"(",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"}),"));\n"]})}),"\n",(0,a.jsx)(e.p,{children:"This same workaround applies when defining relations using variants."}),"\n",(0,a.jsxs)(e.h2,{id:"creating-interfaces-with-builderprismainterface",children:["Creating interfaces with ",(0,a.jsx)(e.code,{children:"builder.prismaInterface"})]}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.code,{children:"builder.prismaInterface"})," works just like builder.prismaObject and can be used to define either the\nprimary type or a variant for a model."]}),"\n",(0,a.jsxs)(e.p,{children:["The following example creates a ",(0,a.jsx)(e.code,{children:"User"})," interface, and 2 variants Admin and Member. The ",(0,a.jsx)(e.code,{children:"resolveType"}),"\nmethod returns the typenames as strings to avoid issues with circular references."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaInterface"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"name"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n  }),\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolveType"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," {\n    ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"return"})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"isAdmin"})," ? ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Admin'"})," : ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Member'"}),";\n  },\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Admin'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"interfaces"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"}),"],\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"isAdmin"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeBoolean"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'isAdmin'"}),"),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"variant"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Member'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"interfaces"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"}),"],\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"bio"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'bio'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.p,{children:"When using select mode, it's recommended to add selections to both the interface and the object\ntypes that implement them. Selections are not inherited and will fallback to the default selection\nwhich includes all scalar columns."}),"\n",(0,a.jsx)(e.p,{children:"You will not be able to extend an interface for a different prisma model, doing so will result in an\nerror at build time."}),"\n",(0,a.jsx)(e.h2,{id:"selecting-fields-from-a-nested-graphql-field",children:"Selecting fields from a nested GraphQL field"}),"\n",(0,a.jsxs)(e.p,{children:["By default, the ",(0,a.jsx)(e.code,{children:"nestedSelection"})," function will return selections based on the type of the current\nfield. ",(0,a.jsx)(e.code,{children:"nestedSelection"})," can also be used to get a selection from a field nested deeper inside other\nfields. This is useful if the field returns a type that is not a ",(0,a.jsx)(e.code,{children:"prismaObject"}),", but a field nested\ninside the returned type is."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostRef"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"content"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'content'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostPreview"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"}),">(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'PostPreview'"}),").",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"post"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostRef"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," post,\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"preview"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"string"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"nullable"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"content"}),"?.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"slice"}),"(",(0,a.jsx)(e.span,{className:"hljs-number",children:"10"}),"),\n    }),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"postPreviews"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, ctx, nestedSelection"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"nestedSelection"}),"(\n          {\n            ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// limit the number of postPreviews to load"}),"\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"take"}),": ",(0,a.jsx)(e.span,{className:"hljs-number",children:"2"}),",\n          },\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Look at the selections in postPreviews.post to determine what relations/fields to select"}),"\n          [",(0,a.jsx)(e.span,{className:"hljs-string",children:"'post'"}),"],\n        ),\n      }),\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostPreview"}),"],\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]})," user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"posts"}),",\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"indirect-relations-eg-join-tables",children:"Indirect relations (eg. Join tables)"}),"\n",(0,a.jsxs)(e.p,{children:["If you want to define a GraphQL field that directly exposes data from a nested relationship (many to\nmany relations using a custom join table is a common example of this) you can use the\n",(0,a.jsx)(e.code,{children:"nestedSelection"})," function passed to ",(0,a.jsx)(e.code,{children:"select"}),"."]}),"\n",(0,a.jsx)(e.p,{children:"Given a prisma schema like the following:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsx)(e.code,{children:"model Post {\n  id        Int         @id @default(autoincrement())\n  title     String\n  content   String\n  media     PostMedia[]\n}\n\nmodel Media {\n  id           Int         @id @default(autoincrement())\n  url          String\n  posts        PostMedia[]\n  uploadedBy   User        @relation(fields: [uploadedById], references: [id])\n  uploadedById Int\n}\n\nmodel PostMedia {\n  id      Int   @id @default(autoincrement())\n  post    Post  @relation(fields: [postId], references: [id])\n  media   Media @relation(fields: [mediaId], references: [id])\n  postId  Int\n  mediaId Int\n}\n"})}),"\n",(0,a.jsx)(e.p,{children:"You can define a media field that can pre-load the correct relations based on the graphql query:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostDraft"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, ctx, nestedSelection"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This will look at what fields are queried on Media"}),"\n            ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// and automatically select uploadedBy if that relation is requested"}),"\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"nestedSelection"}),"(\n              ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This arument is the default query for the media relation"}),"\n              ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// It could be something like: `{ select: { id: true } }` instead"}),"\n              ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n            ),\n          },\n        },\n      }),\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Media"}),"],\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"media"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"map"}),"(",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"{ media }"}),") =>"]})," media),\n    }),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Media"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Media'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"url"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'url'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"uploadedBy"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'uploadedBy'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"detecting-unused-query-arguments",children:"Detecting unused query arguments"}),"\n",(0,a.jsxs)(e.p,{children:["Forgetting to spread the ",(0,a.jsx)(e.code,{children:"query"})," argument from ",(0,a.jsx)(e.code,{children:"t.prismaField"})," or ",(0,a.jsx)(e.code,{children:"t.prismaConnection"})," into your\nprisma query can result in inefficient queries, or even missing data. To help catch these issues,\nthe plugin can warn you when you are not using the query argument correctly."]}),"\n",(0,a.jsxs)(e.p,{children:["the ",(0,a.jsx)(e.code,{children:"onUnusedQuery"})," option can be set to ",(0,a.jsx)(e.code,{children:"warn"})," or ",(0,a.jsx)(e.code,{children:"error"})," to enable this feature. When set to\n",(0,a.jsx)(e.code,{children:"warn"})," it will log a warning to the console if Pothos detects that you have not properly used the\nquery in your resolver. Similarly if you set the option to ",(0,a.jsx)(e.code,{children:"error"})," it will throw an error instead.\nYou can also pass a function which will receive the ",(0,a.jsx)(e.code,{children:"info"})," object which can be used to log or throw\nyour own error."]}),"\n",(0,a.jsxs)(e.p,{children:["This check is fairly naive and works by wrapping the properties on the query with a getter that sets\na flag if the property is accessed. If no properties are accessed on the query object before the\nresolver returns, it will trigger the ",(0,a.jsx)(e.code,{children:"onUnusedQuery"})," condition."]}),"\n",(0,a.jsx)(e.p,{children:"It's recommended to enable this check in development to more quickly find potential issues."}),"\n",(0,a.jsxs)(e.h2,{id:"optimized-queries-without-tprismafield",children:["Optimized queries without ",(0,a.jsx)(e.code,{children:"t.prismaField"})]}),"\n",(0,a.jsxs)(e.p,{children:["In some cases, it may be useful to get an optimized query for fields where you can't use\n",(0,a.jsx)(e.code,{children:"t.prismaField"}),"."]}),"\n",(0,a.jsxs)(e.p,{children:["This may be required for combining with other plugins, or because your query does not directly\nreturn a ",(0,a.jsx)(e.code,{children:"PrismaObject"}),". In these cases, you can use the ",(0,a.jsx)(e.code,{children:"queryFromInfo"})," helper. An example of this\nmight be a mutation that wraps the prisma object in a result type."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {...});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<{\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"success"}),": ",(0,a.jsx)(e.span,{className:"hljs-built_in",children:"boolean"}),";\n  post?: ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"}),"\n  }>(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'CreatePostResult'"}),").",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"success"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"boolean"}),"(),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"post"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"nullable"}),":\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"result"}),") =>"]})," result.",(0,a.jsx)(e.span,{className:"hljs-property",children:"post"}),",\n    }),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"mutationField"}),"(\n  ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'createPost'"}),",\n  {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"args"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"string"}),"({ ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"required"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"})," }),\n      ...\n    }),\n  },\n  {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"async"})," (parent, args, context, info) => {\n      ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"if"})," (!",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"validateCreatePostArgs"}),"(args)) {\n        ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"return"})," {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"success"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"false"}),",\n        }\n      }\n\n      ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," post = prisma.",(0,a.jsx)(e.span,{className:"hljs-property",children:"city"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"create"}),"({\n        ...",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"queryFromInfo"}),"({\n          context,\n          info,\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// nested path where the selections for this type can be found"}),"\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"path"}),": [",(0,a.jsx)(e.span,{className:"hljs-string",children:"'post'"}),"]\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// optionally you can pass a custom initial selection, genereally you wouldn't need this"}),"\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// but if the field at `path` is not selected, the initial selection set may be empty"}),"\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"comments"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n          },\n        }),\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"data"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": args.",(0,a.jsx)(e.span,{className:"hljs-property",children:"input"}),".",(0,a.jsx)(e.span,{className:"hljs-property",children:"title"}),",\n          ...\n        },\n      });\n\n      ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"return"})," {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"success"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n        post,\n      }\n    },\n  },\n);\n"]})}),"\n",(0,a.jsx)(e.h2,{id:"relay-integration",children:"Relay integration"}),"\n",(0,a.jsxs)(e.p,{children:["This plugin has extensive integration with the\n",(0,a.jsx)(e.a,{href:"https://pothos-graphql.dev/docs/plugins/relay",children:"relay plugin"}),", which makes creating nodes and\nconnections very easy."]}),"\n",(0,a.jsx)(e.h3,{id:"prismanode",children:(0,a.jsx)(e.code,{children:"prismaNode"})}),"\n",(0,a.jsxs)(e.p,{children:["The ",(0,a.jsx)(e.code,{children:"prismaNode"})," method works just like the ",(0,a.jsx)(e.code,{children:"prismaObject"})," method with a couple of small\ndifferences:"]}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsxs)(e.li,{children:["there is a new ",(0,a.jsx)(e.code,{children:"id"})," option that mirrors the ",(0,a.jsx)(e.code,{children:"id"})," option from ",(0,a.jsx)(e.code,{children:"node"})," method of the relay plugin,\nand must contain a resolve function that returns the id from an instance of the node. Rather than\ndefining a resolver for the id field, you can set the ",(0,a.jsx)(e.code,{children:"field"})," option to the name of a unique\ncolumn or index."]}),"\n"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This set's what database field to use for the nodes id field"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"field"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"})," },\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// fields work just like they do for builder.prismaObject"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["If you need to customize how ids are formatted, you can add a resolver for the ",(0,a.jsx)(e.code,{children:"id"}),", and provide a\n",(0,a.jsx)(e.code,{children:"findUnique"})," option that can be used to load the node by it's id. This is generally not necessary."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"String"}),"(post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"}),") },\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// The return value will be passed as the `where` of a `prisma.post.findUnique`"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"findUnique"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"id"}),") =>"]})," ({ ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Number"}),".",(0,a.jsx)(e.span,{className:"hljs-built_in",children:"parseInt"}),"(id, ",(0,a.jsx)(e.span,{className:"hljs-number",children:"10"}),") }),\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["When executing the ",(0,a.jsx)(e.code,{children:"node(id: ID!)"})," query with a global ID for which prisma cannot find a record in\nthe database, the default behaviour is to throw an error. There are some scenarios where it is\npreferrable to return ",(0,a.jsx)(e.code,{children:"null"})," instead of throwing an error. For this you can add the ",(0,a.jsx)(e.code,{children:"nullable: true"}),"\noption:"]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"String"}),"(post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"}),") },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"nullable"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relation"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'author'"}),"),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h3,{id:"prismaconnection",children:(0,a.jsx)(e.code,{children:"prismaConnection"})}),"\n",(0,a.jsxs)(e.p,{children:["The ",(0,a.jsx)(e.code,{children:"prismaConnection"})," method on a field builder can be used to create a relay ",(0,a.jsx)(e.code,{children:"connection"})," field\nthat also pre-loads all the data nested inside that connection."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"queryType"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaConnection"}),"(\n      {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),",\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"query, parent, args, context, info"}),") =>"]})," prisma.",(0,a.jsx)(e.span,{className:"hljs-property",children:"post"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findMany"}),"({ ...query }),\n      },\n      {}, ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// optional options for the Connection type"}),"\n      {}, ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// optional options for the Edge type),"}),"\n    ),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h4,{id:"options",children:"options"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"type"}),": the name of the prisma model being connected to"]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"cursor"}),": a ",(0,a.jsx)(e.code,{children:"@unique"})," column of the model being connected to. This is used as the ",(0,a.jsx)(e.code,{children:"cursor"})," option\npassed to prisma."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"defaultSize"}),": (default: 20) The default page size to use if ",(0,a.jsx)(e.code,{children:"first"})," and ",(0,a.jsx)(e.code,{children:"last"})," are not provided."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"maxSize"}),": (default: 100) The maximum number of nodes returned for a connection."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"resolve"}),": Like the resolver for ",(0,a.jsx)(e.code,{children:"prismaField"}),", the first argument is a ",(0,a.jsx)(e.code,{children:"query"})," object that should\nbe spread into your prisma query. The ",(0,a.jsx)(e.code,{children:"resolve"})," function should return an array of nodes for the\nconnection. The ",(0,a.jsx)(e.code,{children:"query"})," will contain the correct ",(0,a.jsx)(e.code,{children:"take"}),", ",(0,a.jsx)(e.code,{children:"skip"}),", and ",(0,a.jsx)(e.code,{children:"cursor"})," options based on the\nconnection arguments (",(0,a.jsx)(e.code,{children:"before"}),", ",(0,a.jsx)(e.code,{children:"after"}),", ",(0,a.jsx)(e.code,{children:"first"}),", ",(0,a.jsx)(e.code,{children:"last"}),"), along with ",(0,a.jsx)(e.code,{children:"include"})," options for nested\nselections."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"totalCount"}),": A function for loading the total count for the connection. This will add a\n",(0,a.jsx)(e.code,{children:"totalCount"})," field to the connection object. The ",(0,a.jsx)(e.code,{children:"totalCount"})," method will receive (",(0,a.jsx)(e.code,{children:"connection"}),",\n",(0,a.jsx)(e.code,{children:"args"}),", ",(0,a.jsx)(e.code,{children:"context"}),", ",(0,a.jsx)(e.code,{children:"info"}),") as arguments"]}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"The created connection queries currently support the following combinations of connection arguments:"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"first"}),", ",(0,a.jsx)(e.code,{children:"last"}),", or ",(0,a.jsx)(e.code,{children:"before"})]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"first"})," and ",(0,a.jsx)(e.code,{children:"before"})]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"last"})," and ",(0,a.jsx)(e.code,{children:"after"})]}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"Queries for other combinations are not as useful, and generally requiring loading all records\nbetween 2 cursors, or between a cursor and the end of the set. Generating query options for these\ncases is more complex and likely very inefficient, so they will currently throw an Error indicating\nthe argument combinations are not supported."}),"\n",(0,a.jsx)(e.h3,{id:"relatedconnection",children:(0,a.jsx)(e.code,{children:"relatedConnection"})}),"\n",(0,a.jsxs)(e.p,{children:["The ",(0,a.jsx)(e.code,{children:"relatedConnection"})," method can be used to create a relay ",(0,a.jsx)(e.code,{children:"connection"})," field based on a relation\nof the current model."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:["builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaNode"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"field"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"})," },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Connections can be very simple to define"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"simplePosts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relatedConnection"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),", {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Or they can include custom arguments, and other options"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relatedConnection"}),"(\n      ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'posts'"}),",\n      {\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"args"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"oldestFirst"}),": t.",(0,a.jsx)(e.span,{className:"hljs-property",children:"arg"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"boolean"}),"(),\n        },\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"query"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, context"}),") =>"]})," ({\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"orderBy"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": args.",(0,a.jsx)(e.span,{className:"hljs-property",children:"oldestFirst"})," ? ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'asc'"})," : ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'desc'"}),",\n          },\n        }),\n      },\n      {}, ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// optional options for the Connection type"}),"\n      {}, ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// optional options for the Edge type),"}),"\n    ),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h4,{id:"options-1",children:"options"}),"\n",(0,a.jsxs)(e.ul,{children:["\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"cursor"}),": a ",(0,a.jsx)(e.code,{children:"@unique"})," column of the model being connected to. This is used as the ",(0,a.jsx)(e.code,{children:"cursor"})," option\npassed to prisma."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"defaultSize"}),": (default: 20) The default page size to use if ",(0,a.jsx)(e.code,{children:"first"})," and ",(0,a.jsx)(e.code,{children:"last"})," are not provided."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"maxSize"}),": (default: 100) The maximum number of nodes returned for a connection."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"query"}),": A method that accepts the ",(0,a.jsx)(e.code,{children:"args"})," and ",(0,a.jsx)(e.code,{children:"context"})," for the connection field, and returns\nfiltering and sorting logic that will be merged into the query for the relation."]}),"\n",(0,a.jsxs)(e.li,{children:[(0,a.jsx)(e.code,{children:"totalCount"}),": when set to true, this will add a ",(0,a.jsx)(e.code,{children:"totalCount"})," field to the connection object. see\n",(0,a.jsx)(e.code,{children:"relationCount"})," above for more details."]}),"\n"]}),"\n",(0,a.jsx)(e.h3,{id:"indirect-relations-as-connections",children:"Indirect relations as connections"}),"\n",(0,a.jsxs)(e.p,{children:["Creating connections from indirect relations is a little more involved, but can be acheived using\n",(0,a.jsx)(e.code,{children:"prismaConnectionHelpers"})," with a normal ",(0,a.jsx)(e.code,{children:"t.connection"})," field."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Create a prisma object for the node type of your connection"}),"\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Media"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Media'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  },\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"url"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'url'"}),"),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Create connection helpers for the media type.  This will allow you"}),"\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// to use the normal t.connection with a prisma type"}),"\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," mediaConnectionHelpers = ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaConnectionHelpers"}),"(\n  builder,\n  ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'PostMedia'"}),", ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// this should be the the join table"}),"\n  {\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"nodeSelection"}),") =>"]})," ({\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// select the relation to the media node using the nodeSelection function"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"nodeSelection"}),"({\n        ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// optionally specify fields to select by default for the node"}),"\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n        },\n      }),\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// resolve the node from the edge"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolveNode"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"postMedia"}),") =>"]})," postMedia.",(0,a.jsx)(e.span,{className:"hljs-property",children:"media"}),",\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// additional/optional options"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"maxSize"}),": ",(0,a.jsx)(e.span,{className:"hljs-number",children:"100"}),",\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"defaultSize"}),": ",(0,a.jsx)(e.span,{className:"hljs-number",children:"20"}),",\n  },\n);\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObjectField"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'mediaConnection'"}),", ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]}),"\n  t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"connection"}),"({\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// The type for the Node"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Media"}),",\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// since we are not using t.relatedConnection we need to manually"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// include the selections for our connection"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, ctx, nestedSelection"}),") =>"]})," ({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": mediaConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"getQuery"}),"(args, ctx, nestedSelection),\n    }),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post, args, ctx"}),") =>"]}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// This helper takes a list of nodes and formats them for the connection"}),"\n      mediaConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"resolve"}),"(\n        ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// map results to the list of edges"}),"\n        post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"media"}),",\n        args,\n        ctx,\n      ),\n  }),\n);\n"]})}),"\n",(0,a.jsx)(e.p,{children:"The above example assumes that you are paginating a relation to a join table, where the pagination\nargs are applied based on the relation to that join table, but the nodes themselves are nested\ndeeper."}),"\n",(0,a.jsxs)(e.p,{children:[(0,a.jsx)(e.code,{children:"prismaConnectionHelpers"})," can also be used to manually create a connection where the edge and\nconnections share the same model, and pagination happens directly on a relation to nodes type (even\nif that relation is nested)."]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-ts",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," commentConnectionHelpers = ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaConnectionHelpers"}),"(builder, ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Comment'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"SelectPost"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"comments"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"connection"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": commentConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-property",children:"ref"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, ctx, nestedSelection"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"comments"}),": commentConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"getQuery"}),"(args, ctx, nestedSelection),\n      }),\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"parent, args, ctx"}),") =>"]})," commentConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"resolve"}),"(parent.",(0,a.jsx)(e.span,{className:"hljs-property",children:"comments"}),", args, ctx),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h3,{id:"sharing-connections-objects",children:"Sharing Connections objects"}),"\n",(0,a.jsxs)(e.p,{children:["You can create reusable connection objects by using ",(0,a.jsx)(e.code,{children:"builder.connectionObject"}),"."]}),"\n",(0,a.jsxs)(e.p,{children:["These connection objects can be used with ",(0,a.jsx)(e.code,{children:"t.prismaConnection"}),", ",(0,a.jsx)(e.code,{children:"t.relatedConnection"}),", or\n",(0,a.jsx)(e.code,{children:"t.connection"})]}),"\n",(0,a.jsxs)(e.p,{children:["Shared edges can also be created using ",(0,a.jsx)(e.code,{children:"t.edgeObject"})]}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"CommentConnection"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"connectionObject"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Comment"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// or"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": commentConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-property",children:"ref"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"name"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'CommentConnection'"}),",\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObject"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ...\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"commentsConnection"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"relatedConnection"}),"(\n      ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'comments'"}),",\n      { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"})," },\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// The connection object ref can be passed in place of the connection objectoptions"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"CommentConnection"}),"\n    ),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.h3,{id:"extending-connection-edges",children:"Extending connection edges"}),"\n",(0,a.jsx)(e.p,{children:"In some cases you may want to expose some data from an indirect connection on the edge object."}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," mediaConnectionHelpers = ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaConnectionHelpers"}),"(builder, ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'PostMedia'"}),", {\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"cursor"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),",\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"nodeSelection"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// select the relation to the media node using the nodeSelection function"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"nodeSelection"}),"({}),\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Select additional fields from the join table"}),"\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n  }),\n  ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// resolve the node from the edge"}),"\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolveNode"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"postMedia"}),") =>"]})," postMedia.",(0,a.jsx)(e.span,{className:"hljs-property",children:"media"}),",\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"prismaObjectFields"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),", ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"manualMediaConnection"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"connection"}),"(\n    {\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Media"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"args, ctx, nestedSelection"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": mediaConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"getQuery"}),"(args, ctx, nestedSelection),\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"select"}),": {\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"media"}),": ",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"nestedSelection"}),"({}, [",(0,a.jsx)(e.span,{className:"hljs-string",children:"'edges'"}),", ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'node'"}),"]),\n        },\n      }),\n\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post, args, ctx"}),") =>"]}),"\n        mediaConnectionHelpers.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"resolve"}),"(\n          post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"media"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"map"}),"(",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"{ media }"}),") =>"]})," media),\n          args,\n          ctx,\n        ),\n    },\n    {},\n    ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// options for the edge object"}),"\n    {\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// define the additional fields on the edge object"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"edge"}),") =>"]})," ({\n        ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"createdAt"}),": edge.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'DateTime'"}),",\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// the parent shape for edge fields is inferred from the connections resolve function"}),"\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"media"}),") =>"]})," media.",(0,a.jsx)(e.span,{className:"hljs-property",children:"createdAt"}),",\n        }),\n      }),\n    },\n  ),\n}));\n"]})}),"\n",(0,a.jsx)(e.h3,{id:"relay-utils",children:"Relay Utils"}),"\n",(0,a.jsxs)(e.h4,{id:"parseprismacursor-and-formatprismacursor",children:[(0,a.jsx)(e.code,{children:"parsePrismaCursor"})," and ",(0,a.jsx)(e.code,{children:"formatPrismaCursor"})]}),"\n",(0,a.jsx)(e.p,{children:"These functions can be used to manually parse and format cursors that are compatible with prisma\nconnections."}),"\n",(0,a.jsxs)(e.p,{children:["Parsing a cursor will return the value from the column used for the cursor (often the ",(0,a.jsx)(e.code,{children:"id"}),"), this\nvalue may be an array or object when a compound index is used as the cursor. Similarly, to format a\ncursor, you must provide the column(s) that make up the cursor."]}),"\n",(0,a.jsx)(e.h2,{id:"using-prisma-without-a-plugin",children:"Using Prisma without a plugin"}),"\n",(0,a.jsxs)(e.p,{children:["Using prisma without a plugin is relatively straight forward using the ",(0,a.jsx)(e.code,{children:"builder.objectRef"})," method."]}),"\n",(0,a.jsx)(e.p,{children:"The easiest way to create types backed by prisma looks something like:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"import"})," { ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"}),", ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"}),", ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"})," } ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"from"})," ",(0,a.jsx)(e.span,{className:"hljs-string",children:"'@prisma/client'"}),";\n\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," db = ",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"new"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PrismaClient"}),"();\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"}),">(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),");\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"}),">(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),");\n\n",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"}),"],\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]}),"\n        db.",(0,a.jsx)(e.span,{className:"hljs-property",children:"post"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findMany"}),"({\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"authorId"}),": user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"})," },\n        }),\n    }),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," db.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findUniqueOrThrow"}),"({ ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"authorId"})," } }),\n    }),\n  }),\n});\n\nbuilder.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"queryType"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"me"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"root, args, ctx"}),") =>"]})," db.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findUniqueOrThrow"}),"({ ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": ctx.",(0,a.jsx)(e.span,{className:"hljs-property",children:"userId"})," } }),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsxs)(e.p,{children:["This sets up User, and Post objects with a few fields, and a ",(0,a.jsx)(e.code,{children:"me"})," query that returns the current\nuser. There are a few things to note in this setup:"]}),"\n",(0,a.jsxs)(e.ol,{children:["\n",(0,a.jsxs)(e.li,{children:["We split up the ",(0,a.jsx)(e.code,{children:"builder.objectRef"})," and the ",(0,a.jsx)(e.code,{children:"implement"})," calls, rather than calling\n",(0,a.jsx)(e.code,{children:"builder.objectRef(...).implement(...)"}),". This prevents typescript from getting tripped up by the\ncircular references between posts and users."]}),"\n",(0,a.jsxs)(e.li,{children:["We use ",(0,a.jsx)(e.code,{children:"findUniqueOrThrow"})," because those fields are not nullable. Using ",(0,a.jsx)(e.code,{children:"findUnique"}),", prisma will\nreturn a null if the object is not found. An alternative is to mark these fields as nullable."]}),"\n",(0,a.jsxs)(e.li,{children:["The refs to our object types are called ",(0,a.jsx)(e.code,{children:"UserObject"})," and ",(0,a.jsx)(e.code,{children:"PostObject"}),", this is because ",(0,a.jsx)(e.code,{children:"User"})," and\n",(0,a.jsx)(e.code,{children:"Post"})," are the names of the types imported from prisma. We could instead alias the types when we\nimport them so we can name the refs to our GraphQL types after the models."]}),"\n"]}),"\n",(0,a.jsx)(e.p,{children:"This setup is fairly simple, but it is easy to see the n+1 issues we might run into. Prisma helps\nwith this by batching queries together, but there are also things we can do in our implementation to\nimprove things."}),"\n",(0,a.jsx)(e.p,{children:"One thing we could do if we know we will usually be loading the author any time we load a post is to\nmake the author part of shape required for a post:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"}),">(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'User'"}),");\n",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// We add the author here in the objectRef"}),"\n",(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"})," & { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"})," }>(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),");\n\n",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"email"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'email'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"posts"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": [",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"}),"],\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"user"}),") =>"]}),"\n        db.",(0,a.jsx)(e.span,{className:"hljs-property",children:"post"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findMany"}),"({\n          ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// We now need to include the author when we query for posts"}),"\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"include"}),": {\n            ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),",\n          },\n          ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"authorId"}),": user.",(0,a.jsx)(e.span,{className:"hljs-property",children:"id"})," },\n        }),\n    }),\n  }),\n});\n\n",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-comment",children:"// Now we can just return the author from the post instead of querying for it"}),"\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]})," post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"author"}),",\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.p,{children:"We may not always want to query for the author though, so we could make the author optional and fall\nback to using a query if it was not provided by the parent resolver:"}),"\n",(0,a.jsx)(e.pre,{children:(0,a.jsxs)(e.code,{className:"hljs language-typescript",children:[(0,a.jsx)(e.span,{className:"hljs-keyword",children:"const"})," ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"})," = builder.",(0,a.jsx)(e.span,{className:"hljs-property",children:"objectRef"}),"<",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"Post"})," & { author?: ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"User"})," }>(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'Post'"}),");\n\n",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"PostObject"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"implement"}),"({\n  ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"fields"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"t"}),") =>"]})," ({\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeID"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'id'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"title"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"exposeString"}),"(",(0,a.jsx)(e.span,{className:"hljs-string",children:"'title'"}),"),\n    ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"author"}),": t.",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"field"}),"({\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"type"}),": ",(0,a.jsx)(e.span,{className:"hljs-title class_",children:"UserObject"}),",\n      ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"resolve"}),": ",(0,a.jsxs)(e.span,{className:"hljs-function",children:["(",(0,a.jsx)(e.span,{className:"hljs-params",children:"post"}),") =>"]}),"\n        post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"author"})," ?? db.",(0,a.jsx)(e.span,{className:"hljs-property",children:"user"}),".",(0,a.jsx)(e.span,{className:"hljs-title function_",children:"findUnique"}),"({ ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"rejectOnNotFound"}),": ",(0,a.jsx)(e.span,{className:"hljs-literal",children:"true"}),", ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"where"}),": { ",(0,a.jsx)(e.span,{className:"hljs-attr",children:"id"}),": post.",(0,a.jsx)(e.span,{className:"hljs-property",children:"authorId"})," } }),\n    }),\n  }),\n});\n"]})}),"\n",(0,a.jsx)(e.p,{children:"With this setup, a parent resolver has the option to include the author, but we have a fallback\nincase it does not."}),"\n",(0,a.jsx)(e.p,{children:"There are other patterns like data loaders than can be used to reduce n+1 issues, and make your\ngraph more efficient, but they are too complex to describe here."}),"\n",(0,a.jsx)(e.h2,{id:"input-types",children:"Input types"}),"\n",(0,a.jsxs)(e.p,{children:["To create input types compatible with the prisma client, you can check out the\n",(0,a.jsx)(e.a,{href:"https://pothos-graphql.dev/docs/plugins/prisma-utils",children:"prisma-utils plugin"})]})]})}e.default=function(){let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return(0,a.jsx)(r,Object.assign({},s,{children:(0,a.jsx)(h,s)}))}}},function(s){s.O(0,[8430,3210,9774,2888,179],function(){return s(s.s=8214)}),_N_E=s.O()}]);