nexus-plugin-prisma icon indicating copy to clipboard operation
nexus-plugin-prisma copied to clipboard

Property 'model' does not exist on type 'ObjectDefinitionBlock<"MyModel">' when deploying with serverless and typescript

Open sfratini opened this issue 4 years ago • 14 comments

I understand Google brings up a few issues about this and I am 99% sure this has to do with my TS config and/or how the types are loaded but can't seem to find where the issue is in my particular setup.

For background I am using:

  • @nexus/schema
  • prisma2
  • serverless
  • serverless plugin for typescript
  • typescript 3.9.7
  • apollo server

Basically, I would want to use serverless to deploy a lambda function into AWS using Apollo server. tsc command finished correctly. A ts-node transpile of my graphql.ts also finishes without issues, however my serverless deployment is failing.

Some code:

//handler.js
import { ApolloServer } from 'apollo-server-lambda';

import { schema } from '../graphql/schema';
import { createContext } from './contextLambda';

const apollo = new ApolloServer({
    schema,
    context: createContext,
    introspection: process.env.NODE_ENV !== 'production',
    playground: {    
        endpoint: "/dev/graphql"
    }
  });

exports.graphqlHandler = apollo.createHandler({
    cors: {
      origin: '*',
      credentials: false,
    }
  });
//contextLambda.ts

import { PrismaClient } from '@prisma/client';
import { PubSub } from 'graphql-subscriptions';

const prisma = new PrismaClient();
const { JWT_SECRET = "" } = process.env;

export interface Context {
  prisma: PrismaClient;
  // db: PrismaClient;
  pubsub: PubSub;
  appSecret: string;
  headers: any;
  functionName: string;
  event: any;
  context: any;
}

const pubsub = new PubSub();

export function createContext({ event, context } : {event: any, context: any}): Context {
  return {
    prisma,
    // db: prisma,
    pubsub,
    appSecret: JWT_SECRET,
    headers: event.headers,
    functionName: context.functionName,
    event,
    context,
  };
}
//schema.ts
import { makeSchema } from '@nexus/schema';
import { nexusSchemaPrisma } from 'nexus-plugin-prisma/schema';
import * as graphqlTypes from './graphql';
import * as path from 'path'

export const schema = makeSchema({

    shouldGenerateArtifacts: false,

    types: graphqlTypes,

    plugins: [
      nexusSchemaPrisma({
          experimentalCRUD: true
      })
    ],

    typegenAutoConfig: {
        contextType: 'Context.Context',
        sources: [
          {
            source: '@prisma/client',
            alias: 'client'
          },
          {
            source: require.resolve('./context'),
            alias: 'Context',
          }
        ]
      },
 
    outputs: {
        schema: path.join(__dirname, './schema.graphql'),
        typegen: path.join(__dirname, './typegen.ts')
    }

});

Some config:

//package.json
{
  "name": "myproject",
  "version": "0.1.0",
  "private": true,
  "type": "module",
  "dependencies": {
    "@aws-amplify/ui-react": "0.2.9",
    "@material-ui/core": "4.9.3",
    "@material-ui/icons": "4.9.1",
    "@material-ui/lab": "4.0.0-alpha.43",
    "@nexus/schema": "0.14.0",
    "@testing-library/jest-dom": "4.2.4",
    "@testing-library/react": "9.3.2",
    "@testing-library/user-event": "7.1.2",
    "apollo-server": "2.16.0",
    "apollo-server-lambda": "2.16.0",
    "formik": "2.1.4",
    "graphql": "15.3.0",
    "nexus": "0.25.0",
    "nexus-plugin-prisma": "0.16.1",
    "react": "16.12.0",
    "react-dom": "16.12.0",
    "react-redux": "7.2.0",
    "react-router-dom": "5.1.2",
    "react-scripts": "3.4.0",
    "recharts": "2.0.0-beta.1",
    "recompose": "0.30.0",
    "redux": "4.0.5",
    "redux-persist": "6.0.0",
    "redux-thunk": "2.3.0",
    "typescript": "3.9.6",
    "yup": "0.28.1"
  },
  "scripts": {
    "startWeb": "react-scripts start",
    "buildWeb": "react-scripts build",
    "testWeb": "react-scripts test",
    "ejectWeb": "react-scripts eject",
    "devApi": "ts-node-dev --no-notify --respawn --transpile-only api/apollo/server.ts",
    "startApi": "node dist/server",
    "cleanApi": "rm -rf dist",
    "buildApi": "npm -s run clean && npm -s run generate && tsc",
    "lint": "eslint src/**/**/*.ts tests/**/**/*.ts",
    "tsc": "tsc",
    "devNexus": "nexus dev",
    "buildNexus": "nexus build",
    "generate": "npm -s run generate:prisma && npm -s run generate:nexus",
    "generate:prisma": "prisma generate",
    "generate:nexus": "ts-node --transpile-only api/graphql/schema.ts",
    "migrate:save": "prisma migrate save --experimental",
    "migrate:up": "prisma migrate up --experimental",
    "migrate:down": "prisma migrate down 1 --experimental"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  },
  "devDependencies": {
    "@prisma/cli": "2.1.3",
    "serverless-plugin-typescript": "^1.1.9",
    "ts-node-dev": "1.0.0-pre.52"
  }
}

//tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "rootDir": ".",
    "typeRoots": ["node_modules/@types", "types"],
    "plugins": [{ "name": "nexus/typescript-language-service" }]
  },
  "include": [
    "src",
    "api/**/*",
    "types.d.ts",
    "types.ts",
    "."
  ]
}

//babel.config.json
{
"presets": ["es2015"]
}

Tried:

  • adding type: module into the package.json
  • renaming my handler to have mjs extension
  • Confirmed tsc runs fine.
  • Generated nexus schema and well as prisma schema.
  • Nuke node_modules and start over.

As a side note, building nexus also fails but due to another issue I believe, which I will deal when I have to:

1125 ✕ nexus reflection failed
       | error  Error: Cannot use GraphQLScalarType "DateTime" from another module or realm.
       |        
       |        Ensure that there is only one instance of "graphql" in the node_modules
       |        directory. If different versions of "graphql" are the dependencies of other
       |        relied on modules, use "resolutions" to ensure only one version is installed.
       |        
       |        https://yarnpkg.com/en/docs/selective-version-resolutions
       |        
       |        Duplicate "graphql" modules cannot be used at the same time since different
       |        versions may have different capabilities and behavior. The data from one
       |        version used in the function from another could produce confusing and
       |        spurious results.

Another note is that I posted here since the repo for the serverless plugin seems to be either outdated or not being monitored (not very active)

Thanks!

sfratini avatar Jul 27 '20 11:07 sfratini

Also running into this

cyrus-za avatar Aug 05 '20 14:08 cyrus-za

Used this template as a recipe: https://github.com/echobind/bisonapp/tree/master/template And got similar error:

{
  |          stack: 'Error: Cannot use GraphQLScalarType "DateTime" from another module or realm.\n' +
  |            'Ensure that there is only one instance of "graphql" in the node_modules\n' +
  |            'directory. If different versions of "graphql" are the dependencies of other\n' +
  |            'relied on modules, use "resolutions" to ensure only one version is installed.\n' +
  |            'https://yarnpkg.com/en/docs/selective-version-resolutions\n' +
  |            'Duplicate "graphql" modules cannot be used at the same time since different\n' +
  |            'versions may have different capabilities and behavior. The data from one\n' +
  |            'version used in the function from another could produce confusing and\n' +
  |            'spurious results.\n' +
  |            '    at instanceOf (~/node_modules/graphql/jsutils/instanceOf.js:29:13)\n'
  |        }

First, used resolutions as suggested, but then saw this: image

Both ways worked

LexSwed avatar Aug 18 '20 19:08 LexSwed

Used this template as a recipe: https://github.com/echobind/bisonapp/tree/master/template And got similar error:

{
  |          stack: 'Error: Cannot use GraphQLScalarType "DateTime" from another module or realm.\n' +
  |            'Ensure that there is only one instance of "graphql" in the node_modules\n' +
  |            'directory. If different versions of "graphql" are the dependencies of other\n' +
  |            'relied on modules, use "resolutions" to ensure only one version is installed.\n' +
  |            'https://yarnpkg.com/en/docs/selective-version-resolutions\n' +
  |            'Duplicate "graphql" modules cannot be used at the same time since different\n' +
  |            'versions may have different capabilities and behavior. The data from one\n' +
  |            'version used in the function from another could produce confusing and\n' +
  |            'spurious results.\n' +
  |            '    at instanceOf (~/node_modules/graphql/jsutils/instanceOf.js:29:13)\n'
  |        }

First, used resolutions as suggested, but then saw this: image

Both ways worked

Hello can you please provide me with an example of your setup, webpack.config, package.json, because I'm running into the graphql duplicate problem with nexus, please!!

frankyveras2 avatar Sep 11 '20 02:09 frankyveras2

@sfratini did you ever resolve this? I have a similar issue. @LexSwed 's solution seems to only be valid for projects using nexus framework, whereas both of our projects are using @nexus/schema. I have tried using yarn's resolutions feature as suggested by the error message but no luck so far.

link2cory avatar Sep 16 '20 19:09 link2cory

@sfratini did you ever resolve this? I have a similar issue. @LexSwed 's solution seems to only be valid for projects using nexus framework, whereas both of our projects are using @nexus/schema. I have tried using yarn's resolutions feature as suggested by the error message but no luck so far.

First we moved to nexus altogether, as the latest version uses apollo server which is the reason I was using nexus/schema separately. Everything worked fine out of the box. I assume a combination of TS and some other issues I did not have more time to invest.

Eventually I found a few issues related to the queries and I had to give up. We moved to sequelize + apollo server + writing the schema manually. We have 150+ tables so it would have been great to use this framework but I had too many blocks and this is a large project so I don't want to risk using a project which still has a few things to resolve.

Sorry I can't be of more help but feel free to contact me.

sfratini avatar Sep 16 '20 19:09 sfratini

No worries, I appreciate the update! Maybe I'll look at switching over to the framework too. Good luck with your project!

link2cory avatar Sep 16 '20 20:09 link2cory

Hey @link2cory, any luck with this? I'm still seeing Property 'crud' does not exist on type 'ObjectDefinitionBlock<"Mutation"> when trying to deploy to heroku.

davidhlee avatar Sep 29 '20 18:09 davidhlee

@davidhlee So re-reading the thread I don't think that my issue was the same as the underlying problem that sfratini originally reported, but his secondary issue. Receiving the error:

error  Error: Cannot use GraphQLScalarType "DateTime" from another module or realm.

at runtime. This error comes from graphql-js itself and I don't think that the issues are related, but since people were posting solutions (that weren't working for me) to that issue I hopped on the thread. I might as well point to the issue I opened with graphql-js in case it can be of help to you and your setup. Essentially it came down to my serverless packaging plugin's (serverless-offline-plugin) default packaging strategy being incompatible with graphql-js's runtime checks creating a false positive for multiple graphql instances, which they specifically do not allow for reasons stated in the error message. Here is the link to the issue including a workaround: https://github.com/graphql/graphql-js/issues/2801

Hoping that can be of use to someone, but I suspect that it won't be of much use to you, sorry! Good luck though!

link2cory avatar Sep 30 '20 17:09 link2cory

Still no solution for this error? With nexus framework being shut down, this error is annoying!

Other related error is: Property 'crud' does not exist on type 'OutputDefinitionBlock

jawosis avatar Oct 02 '20 09:10 jawosis

With nexus framework being shut down

What do you mean @jawosis ?

sfratini avatar Oct 02 '20 13:10 sfratini

@sfratini As of 2 days ago they are ending Nexus Framework development and moving efforts over to Nexus/schema: https://github.com/prisma-labs/graphql-framework-experiment I'm currently converting my Nexus Framework to Schema and have run in to this issue as well

uncvrd avatar Oct 02 '20 17:10 uncvrd

@sfratini As of 2 days ago they are ending Nexus Framework development and moving efforts over to Nexus/schema: https://github.com/prisma-labs/graphql-framework-experiment I'm currently converting my Nexus Framework to Schema and have run in to this issue as well

Oh yikes. Well, I think it is an amazing tool/framework but I did found some very specific issues which require workaround. I am just simply starting a big project from scratch so I can't risk having an unstable code on the core of the API. Specially since my concerns were confirmed by shutting down the framework. Which, BTW, I think is the right approach. I can see the schema being a completely different and stable tool in the future.

We moved to a manual schema, sequelize as ORM (Prisma is great but had many issues with the integration, maybe it was Nexus and not Prisma) and apollo server. So far so good, although we are advancing slower than if using the framework.

sfratini avatar Oct 02 '20 17:10 sfratini

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

djm avatar Jan 04 '21 23:01 djm

I don't know how obvious this is supposed to be, but your project should have a tsconfig.json (even one that just contains {}). Otherwise the plugin won't work for whatever reason.

domq avatar Aug 30 '21 20:08 domq