prisma-labs / graphql-framework-experiment

Code-First Type-Safe GraphQL Framework
https://nexusjs.org
MIT License
674 stars 66 forks source link

Local typing error when running nexus build #1352

Open scleriot opened 4 years ago

scleriot commented 4 years ago

Description

When building with nexus build I get typing error that I don't get when running nexus dev:

> nexus build

1499 ● nexus:build get used plugins
● nexus:plugin:nexusPluginPrisma Running generators
● nexus:build starting reflection
● nexus:build building typescript program
● nexus:build compiling a production build
src/app.ts:38:9 - error TS2339: Property 'prisma' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.

38     req.prisma = new PrismaClient()
etc...

    at Object.emitTSProgram (/home/scleriot/Dev/perso/customer-success/backend/node_modules/nexus/src/lib/tsc.ts:108:11)
    at Object.buildNexusApp (/home/scleriot/Dev/perso/customer-success/backend/node_modules/nexus/src/lib/build/build.ts:97:3)
    at process._tickCallback (internal/process/next_tick.js:68:7)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! customersuccess-backend@1.0.0 build: `nexus build`
npm ERR! Exit status 1

Local typing is defined in:

express/index.d.ts looks like this:

declare namespace Express {
  interface Request {
      userId: string
      prisma: import('@prisma/client').PrismaClient
  }
}

Here is the corresponding tsconfig.json:

{
    "compilerOptions": {
      "target": "esnext",
      "module": "commonjs",
      "strict": true,
      "jsx": "preserve",
      "moduleResolution": "node",
      "experimentalDecorators": true,
      "esModuleInterop": true,
      "allowSyntheticDefaultImports": true,
      "noImplicitAny": false,
      "sourceMap": true,
      "strictNullChecks": false,
      "noEmit": true,
      "lib": [
        "esnext"
      ],
      "typeRoots" : ["node_modules/@types", "types"],
      "plugins": [{ "name": "nexus/typescript-language-service" }],
      "rootDir": "."
    },
    "include": [".", "types.d.ts"]
}

Nexus Report

I get the following error when doing nexus report:

TypeError: Object.fromEntries is not a function
    at Object.getNexusReport (/home/scleriot/Dev/perso/customer-success/backend/node_modules/nexus/dist/lib/report.js:27:30)
    at Report.parse (/home/scleriot/Dev/perso/customer-success/backend/node_modules/nexus/dist/cli/commands/report.js:23:39)
mohe2015 commented 4 years ago

Can you show the part of app.ts please? (You can remove the parts you don't want to show)

scleriot commented 4 years ago

Sure:

import { server, settings, use } from 'nexus'
import { prisma } from 'nexus-plugin-prisma'
import { PrismaClient } from '@prisma/client'

// ...

server.express.use((req, res, next) => {
    req.prisma = new PrismaClient()
    next()
})

Right now my workaround for completing the build is commenting line 78 of node_modules/nexus/dist/lib/tsc.js:

if (allDiagnostics.length > 0) {
        console.log(project.formatDiagnosticsWithColorAndContext(allDiagnostics));
        // throw new Error(project.formatDiagnosticsWithColorAndContext(allDiagnostics));
    }
mohe2015 commented 4 years ago

According to the tutorial you should either just do

use(prisma())

to make prisma available in the context (as db I think) or you can use:

const db = new PrismaClient();

use(
  prisma({
    client: {
      instance: db,
    },
    features: {
      crud: true, // only if you want that
    },
  })
);

if you need to do customizations.

scleriot commented 4 years ago

@mohe2015 Thanks, but this issue is not about Prisma usage, but a bug report regarding TypeScript typechecking done by nexus build

mohe2015 commented 4 years ago

@scleriot I know but the error Property 'prisma' does not exist on type 'Request<ParamsDictionary, any, any, ParsedQs>'.looks like you are not supposed to manipulate the request object. Instead you are supposed to manipulate the context object e.g. using my method or using schema.addToContext Edit:

schema.addToContext(async ({req, res}) => {
  return {
    db: new PrismaClient(), // If you really want to create a new one for every request
    userId: getItSomehow(req)
  };
});
scleriot commented 4 years ago

Actually I'm trying no extend not only NexusContext type but also Express

I should be able to extend any typings, in types/ directory for example as explained here: https://nexusjs.org/guides/project-layout#local-package-typings.

Works well with nexus dev, error happens only at build time