graphql-nexus / nexus-plugin-prisma

Deprecated
MIT License
829 stars 118 forks source link

Property 'model' does not exist on type 'ObjectDefinitionBlock..., Property 'crud' does not exist on type 'OutputDefinitionBlock... #878

Open jawosis opened 3 years ago

jawosis commented 3 years ago

I know this is not a new issue, but even after reading through related issues and studying the adoption guides, I cannot figure out how to successfully build a simple @nexus/schema project.

I have setup a project as described in the current tutorial docs with following relevant files:

// api/schema.ts
import { makeSchema } from '@nexus/schema'
import { nexusPrisma } from 'nexus-plugin-prisma'
import { join } from 'path'
import * as typeDefs from './graphql'

export const schema = makeSchema({
  types: typeDefs,
  plugins: [
    nexusPrisma({
      experimentalCRUD: true
    }),
  ],
  outputs: {
    typegen: join(__dirname, '..', 'nexus-typegen.ts'),
    schema: join(__dirname, '..', 'schema.graphql')
  },
  typegenAutoConfig: {
    sources: [
      {
        source: require.resolve('.prisma/client/index.d.ts'),
        alias: "prisma",
      },
      {
        source: require.resolve("./context"),
        alias: "ContextModule",
      },
    ],
    contextType: "ContextModule.Context",
  },
})
// api/graphql/index.ts
export * from './User'
// api/graphql/User.ts
import { objectType, extendType } from '@nexus/schema'

export const User = objectType({
  name: 'User',
  definition(t) {
    t.model.email()
    t.model.name()
  }
})

export const UserQuery = extendType({
  type: 'Query',
  definition(t) {
    t.crud.users()
  },
})

When running ts-node-dev api/schema.ts those errors are thrown: Property 'model' does not exist on type 'ObjectDefinitionBlock Property 'crud' does not exist on type 'OutputDefinitionBlock

Following dependencies are in use: "@nexus/schema": "0.16.0", "@prisma/client": "2.7.0", "@prisma/cli": "2.7.0", "nexus-plugin-prisma": "0.20.0", "ts-node-dev": "^1.0.0-pre.63"

Can anyone please help?

raymclee commented 3 years ago

i just was using nexus and just migrated to nexus/schema and having the same issue

jawosis commented 3 years ago

After I restarted my development machine it suddenly worked! I cannot really tell why, because I also added express middleware to the server stack and then I was suddenly able to run a ts-node-dev api/schema.ts to create the required type definitions.

ZaneH commented 3 years ago

This actually sounds relevant to my issue as well: https://github.com/graphql-nexus/schema/issues/523

In addition to getting the "getTypeMap" issue, all of my crud/model fields are null. Let me know if you remember what (if anything) changed. I just tried a reboot...no luck

uncvrd commented 3 years ago

@jawosis I still haven't gotten this to work, but i have a question. When looking at your code I see:

source: require.resolve('.prisma/client/index.d.ts'),

Shouldn't this be pointing to, ../node_modules/.prisma/client/index.d.ts? Or at least that's what I think it should be haha

But yea, if you have a sudden lightbulb moment on what caused it to work, let us know :D

rvcas commented 3 years ago

might be related to this error I see when running: ts-node-dev --transpile-only src/app.ts

TypeError: Cannot read property 'some' of undefined
    at transformArg (/Users/arubaito/thelab/pedra/azul/node_modules/nexus-plugin-prisma/src/dmmf/transformer.ts:91:33)
rvcas commented 3 years ago

I tried the fix from this PR: https://github.com/graphql-nexus/nexus-plugin-prisma/pull/876

and everything seems to be working well now. seems to be a typo in a function in the transformer.

Pkmmte commented 3 years ago

In my case, I had "graphql": "15.3.0" in my package.json when I ran into this issue.

Downgrading back to 14.7.0, deleting node_modules, running npm install, and generating prisma/nexus again helped resolve this issue for me.

rizrmd commented 3 years ago

14.7.0

This does not work on my machine

VNadygin commented 3 years ago

@jawosis I think the doc is a bit unclear. My problem was that ctx.db is not passed to apollo server. I solve is by passing context:

// db.tx
import { PrismaClient } from "@prisma/client";

export const db = new PrismaClient();
// app.tx
import { db } from "./db";

const apollo = new ApolloServer({
  schema,
  context: () => ({
    db,
  }),
});
MikeAliG commented 3 years ago

Hello, any updates on this?

sarakusha commented 3 years ago

workaround At the first start, the types have not yet been defined, and then the crud and the model will have any type. But after generating the types ("nexus:reflect": "NEXUS_SHOULD_EXIT_AFTER_REFLECTION=true ts-node src"), they will get the desired type.


// helper.ts
import { ObjectDefinitionBlock } from '@nexus/schema/dist/definitions/objectType';

type PickType<T, K extends string> = T extends Pick<any, K> ? T[K] : any;

type CRUD<TypeName extends string> = PickType<NexusGenCustomOutputProperties<TypeName>, 'crud'>;

type Model<TypeName extends string> = PickType<NexusGenCustomOutputProperties<TypeName>, 'model'>;

export const crud = <TypeName extends string>(t: ObjectDefinitionBlock<TypeName>): CRUD<TypeName> =>
  (t as any).crud;

export const model = <TypeName extends string>(
  t: ObjectDefinitionBlock<TypeName>
): Model<TypeName> => (t as any).model;

// api/graphql/User.ts
import { objectType, extendType } from '@nexus/schema'
import { crud, model } from '.../helper.ts'

export const User = objectType({
  name: 'User',
  definition(t) {
    model(t).email()
    model(t).name()
/*
   model(t).email().name()
*/
  }
})

export const UserQuery = extendType({
  type: 'Query',
  definition(t) {
    crud(t).users()
  },
})

// tsconfig.json
{
  "compilerOptions": {},
  "include": [
    "./typegen.d.ts", // <------ **TYPEGEN**
    "./src"
  ],
}

// src/index.ts
const schema = makeSchema({
  typegenAutoConfig: {
    sources: [
      {
        source: require.resolve('.prisma/client/index.d.ts'),
        alias: 'prisma',
      },
      {
        source: require.resolve('./context'),
        alias: 'ContextModule',
      },
    ],
    contextType: 'ContextModule.Context',
  },
  outputs: {
    schema: path.join(__dirname, '../schema.graphql'),
    typegen: path.join(__dirname, '../typegen.d.ts'), // <--- **TYPEGEN**
  },
  types: [types, jsonScalar, dateTimeScalar],
  shouldExitAfterGenerateArtifacts: Boolean(process.env.NEXUS_SHOULD_EXIT_AFTER_REFLECTION),
  plugins: [nexusPrisma({ experimentalCRUD: true, paginationStrategy: 'prisma' })],
});
joelbowen commented 3 years ago

In my case, I simply could not get my builds to deploy in CI, though they worked locally, typegen simply did not alleviate these errors during deployment on Heroku.

I ended up changing the destination folders to my generated folder in src, and committing them to the repo. Git-hooks will help me keep things in sync, sure, but I couldn't find a way to properly bootstrap a build in CI.

makeSchema({
...
  plugins: [
    nexusPrisma({
      experimentalCRUD: true,
      // UPDATED TO SAVE IN MY GENERATED FOLDER
      outputs: { typegen: __dirname + '/generated/nexus-prisma.d.ts' },
    }),
  ],
  outputs: {
    schema: __dirname + '/../schema.graphql',
    // CHANGED TO .d.ts FILE
    typegen: __dirname + '/generated/nexus.d.ts',
  },
...
})

I also added these files explicitly to my src in tsconfig.json but I don't think that step is necessary.

djm commented 3 years ago

Just a quick fix dump for anyone not using ts-node-dev who is still hitting the Property 'model' does not exist on type ObjectDefinitionBlock or Property 'crud' does not exist on type ObjectDefinitionBlock...

Ensure your type generations are getting output where you think they are.

More on this here, with detailed makeSchema example.

Using versions: nexus: v1.0.0 nexus-plugin-prisma: v0.27.0 @prisma/client: v2.13.1

gex commented 3 years ago

i had the same problem (model and crud properties do not exist on types) and @djm's solution while wasn't perfect for me pointed me to the right direction (thanks!).

my versions are:

in my understanding there are 3 different type generations in play:

type generation

prisma types

yarn prisma generate provides this and the file's location is node_modules/.prisma/client/index.ts (it took some time while i figured out that .prisma is not a typo :D). this is strictly prisma related and it's useful when you manually call prisma in your resolver (e.g. prisma.yourModel.findMany()).

nexus plugin prisma types

the nexusPrisma() plugin imported from the nexus-plugin-prisma package generates this. you can set the path by adding an outputs option to the plugin (e.g. nexusPrisma({ outputs: 'yourPath' })) but since the default path is node_modules/@types/typegen-nexus-plugin-prisma/index.d.ts typescript already knows about this so it's not necessary to set this value. the file contains the types for the graphqlized prisma schema, like interfaces for the models, inputs, etc.

nexus types

the makeSchema() function imported from the nexus package generates this. this is where the missing properties are. you can set the path by adding outputs or outputs/typegen option to the config (e.g. makeSchema({ outputs: true })). there are a few different scenarios now:

1. { outputs: true }

i went with this originally because it says true means default paths and the default path for generated types is node_modules/@types/nexus-typegen/index.d.ts. unfortunately there is no generated file in node_modules because the typegen file path is not set, it remains null.

2. { outputs: { typegen: true } }

same goes for this, while the interface allows using a boolean here, it gets completely ignored.

3. { outputs: { typegen: 'yourPath' } }

in my experience this is the only working setup to make it work. with this you can set the file name of the missing generated types.

solutions

now that we finally know how to generate those types we have different ways to make typescript discover them.

leverage the node_modules/@types directory

since typescript is aware of the content of this directory and this is what nexus would do by default according to the tsdoc tag i added this to my makeSchema config:

makeSchema({
  plugins: [nexusPrisma()],
  types: [/* ... */],
  sourceTypes: {
    modules: [
      {
        module: require.resolve('.prisma/client/index.d.ts'),
        alias: 'prisma'
      }
    ]
  },
  contextType: { /* ... */ },
  outputs: {
    schema: true, // means schema.graphql in the root
    typegen: join(
      process.cwd(),
      'node_modules/@types/nexus-typegen-custom/index.d.ts'
    )
  }
})

i added the -custom prefix to prevent collision with the hopefully-soon-to-be-fixed default path.

add the generated file to tsconfig.json

i guess some people uses the official guide to make this work so here is another way to solve it:

makeSchema({
  plugins: [nexusPrisma()],
  types: [/* ... */],
  sourceTypes: {
    modules: [
      {
        module: require.resolve('.prisma/client/index.d.ts'),
        alias: 'prisma'
      }
    ]
  },
  contextType: { /* ... */ },
  outputs: {
    schema: true, // means schema.graphql in the root
    typegen: path.join(__dirname, 'generated/nexus.d.ts')
  }
})

add typeRoots to tsconfig.json under compilerOptions (your path to the generated directory can be different):

{
  "compilerOptions": {
    "typeRoots": ["./src/generated"]
  }
}

edit: now that i checked all of this again it seems like generating the nexus.d.ts outside of node_modules/@types works without adding typeRoots to my tsconfig.json. it did not work before and i spent some time with this so i could have added something to my config (can it be the rootDir?). i'm somewhat new to typescript so please fix me if i said something stupid above.

jovialcore commented 3 years ago

`src/controllers/user.controller.ts:716:19 - error TS2339: Property 'user_bulk_acc_create' does not exist on type 'PrismaClient<PrismaClientOptions, never, boolean | ((error: Error) => Error) | RejectPerOperation | undefined>'.

716 await dbClient.user_bulk_acc_create.createMany({



`

I get this type of error. please looks like it is related can anyone point me to a simple solution. Thank you 
fullStackDataSolutions commented 2 years ago

I'm having the same issue, what's strange is I've created multiple servers before and never had this issue. So I'm not sure what's causing it. I'm just trying to get a working server at this point.

fullStackDataSolutions commented 2 years ago

I think the issue was caused by not running:

ts-node-dev --transpile-only --respawn src/

I didn't have the --transpile-only and that will do it.