paljs / prisma-tools

Prisma tools to help you generate CRUD system for GraphQL servers
https://paljs.com
MIT License
680 stars 55 forks source link

implementation working with @prisma/clientv3.9.1 using nexus-plugin-prisma with crud support (nexus-prisma is too early stage) #264

Open simonjoom opened 2 years ago

simonjoom commented 2 years ago

Hi there, i did some success to make work the dashboard with prisma3 and the old nexus-plugin-prisma with crud support Just here to share some code and thought , in aim to help others and to save the hack process i use here @paljs last version 4.1 i use last version of nexus-plugin-prisma

nexus-prisma seems still not stable,and i found nexus-plugin-prisma interesting because the crud support

prisma has got some breaking code. https://github.com/graphql-nexus/nexus-plugin-prisma/pull/1010 also thanks https://github.com/graphql-nexus/nexus-plugin-prisma/pull/804 for the help

I did the admin dashboard work and tested with the full-stack-gatsbyjs code example (didnt test for other example)

pal.js code for nexus-plugin-prisma

const pageContent = `
import React from 'react';
import PrismaTable from '../../../components/PrismaTable';

const #{id}: React.FC = () => {
  return <PrismaTable model="#{id}" />;
};

export default #{id};
`

module.exports = {
  backend: {
    generator: 'nexus-plugin-prisma', //change nexus by nexus-plugin-prisma
    adminSettingsPath: 'packages/server/adminSettings.json',
    output: 'packages/server/src/graphql',
  },
  frontend: {
    admin: {
      outPut: 'packages/ui/src/pages/admin/models',
      pageContent,
    },
  },
}

to generate correctly code before to use pal generate hack files to support prisma 3: (thanks https://github.com/graphql-nexus/nexus-plugin-prisma/pull/804 for the help) @paljs/generator/dist/generator.cjs.development.js (well i just copy paste brut code here)

OrderByInput should become OrderByWithRelationInput (else throw error type error in generation) and some adjustment as described on https://github.com/graphql-nexus/nexus-plugin-prisma/pull/804 line 1341

case 'findUnique':
fileContent.push("t.crud.findUnique" + _this.upperModel(modelName.singular) + "()");
break;
case 'findMany':
fileContent.push("t.crud.findMany" + _this.upperModel(modelName.singular) + "({ filtering: true, ordering: true })");
break;
case 'findCount':
if (!exclude.includes('findMany')) {
fileContent.push("t.field('findMany" + _this.upperModel(modelName.singular) + "Count', {\n                    type: 'Int',\n                    args: {\n                      where: '" + model.name + "WhereInput',\n                    },\n                    async resolve(_root, args, ctx) {\n                      return ctx.prisma." + modelName.singular + ".count(args" + (_this.isJS ? '' : ' as any') + ")\n                    },\n                  })");
 }
  break;
case 'findFirst':
if (!exclude.includes('findMany')) {
fileContent.push("t.field('findFirst" + model.name + "', {\n                    type: '" + model.name + "',\n                    args: {\n                      where: '" + model.name + "WhereInput',\n                      orderBy: arg({ type: '" + model.name + "OrderByWithRelationInput' }),\n                      cursor: '" + model.name + "WhereUniqueInput',\n                      skip: 'Int',\n                      take: 'Int',\n                    },\n                    async resolve(_root, args, ctx) {\n                      return ctx.prisma." + modelName.singular + ".findFirst(args" + (_this.isJS ? '' : ' as any') + ")\n                    },\n                  })");
}

transformation for prisma3 https://github.com/graphql-nexus/nexus-plugin-prisma/blob/main/src/naming-strategies.ts : in your code /node_modules/nexus-plugin-prisma/dist/naming-strategies.js

exports.defaultFieldNamingStrategy = {
    //findUnique: (_, modelName) => camelcase_1.default(modelName),
    //findMany: (_, modelName) => camelcase_1.default(pluralize_1.default(modelName)),
    findUnique: (_, modelName) => `findUnique${modelName}`,
    findMany: (_, modelName) =>  `findMany${modelName}`,

server/src/nexusSchema.js add some code to support fully and add crud types

import { makeSchema } from 'nexus'
import * as types from './graphql'
import { paljs } from '@paljs/nexus'
import { nexusPrisma } from 'nexus-plugin-prisma';
import { join } from 'path'

export const schema = makeSchema({
  types,
  plugins: [paljs({ includeAdmin: true }),nexusPrisma({
    // Enable or disable auto-generation of the `crud` abilities.
    experimentalCRUD: true,
    paginationStrategy: "prisma",
    // These are the generation paths for `nexus-plugin-prisma`,
    // it currently generates one typegen file that is unique
    // to your prisma schema. NB: This gets read at RUNTIME, so
    // if your outputting js to a ./dist folder you'll want to
    // take that into account when making the path so that you
    // can instead output into something like `./src/generated`
    // or any other folder that you have your tsconfig.json set
    // up to look into it (rarely is this dist!)
    outputs: {
      typegen: join(
        __dirname,
        'generated',
        'nexus-plugin-prisma-typegen.d.ts',
      ),
    },
  })
],
  outputs: {
    schema: __dirname + '/../schema.graphql',
    typegen: __dirname + '/generated/nexus.ts',
  },
  shouldGenerateArtifacts:true,
  sourceTypes: {
    modules: [
      {
        module: require.resolve('../../../node_modules/.prisma/client/index.d.ts'), //point correctly with the prisma
        alias: 'PrismaClient',
      },
    ],
  },
  contextType: {
    module: join(__dirname, 'context.ts'),
    export: 'Context',
  },
}) 

after making these mods here regenerate paljs

paljs g check your code generated by paljs in server/src/graphql and add some of your customs files (Auth..) in server run npm run generate:prisma and then 'npm run generate:nexus' check output code at the root npm run codegen finally npm run dev work well

Hope to have some interest on it coz seems lot of people struggle to make working new prisma and nexus