Skip to content

Commit

Permalink
CodeGen: Try to generate prisma client if no models are found (redwoo…
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe authored Aug 29, 2022
1 parent 541ae47 commit 0705da1
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
exports[`Generate gql typedefs api 1`] = `
"import { Prisma } from "@prisma/client"
import { GraphQLResolveInfo, GraphQLScalarType, GraphQLScalarTypeConfig } from 'graphql';
import { PrismaModelOne as PrismaPrismaModelOne, PrismaModelTwo as PrismaPrismaModelTwo, Post as PrismaPost, Todo as PrismaTodo } from '@prisma/client';
import { RedwoodGraphQLContext } from '@redwoodjs/graphql-server/dist/functions/types';
export type Maybe<T> = T | null;
export type InputMaybe<T> = Maybe<T>;
Expand Down Expand Up @@ -155,7 +156,7 @@ export type ResolversTypes = {
Redwood: ResolverTypeWrapper<Redwood>;
String: ResolverTypeWrapper<Scalars['String']>;
Time: ResolverTypeWrapper<Scalars['Time']>;
Todo: ResolverTypeWrapper<Todo>;
Todo: ResolverTypeWrapper<PrismaTodo>;
};
/** Mapping between all available schema types and the resolvers parents */
Expand All @@ -172,7 +173,7 @@ export type ResolversParentTypes = {
Redwood: Redwood;
String: Scalars['String'];
Time: Scalars['Time'];
Todo: Todo;
Todo: PrismaTodo;
};
export type requireAuthDirectiveArgs = {
Expand Down
11 changes: 11 additions & 0 deletions packages/internal/src/__tests__/graphqlCodeGen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ afterEach(() => {
jest.restoreAllMocks()
})

jest.mock('@prisma/client', () => {
return {
ModelName: {
PrismaModelOne: 'PrismaModelOne',
PrismaModelTwo: 'PrismaModelTwo',
Post: 'Post',
Todo: 'Todo',
},
}
})

test('Generate gql typedefs web', async () => {
await generateGraphQLSchema()

Expand Down
59 changes: 43 additions & 16 deletions packages/internal/src/generate/graphqlCodeGen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { CodeFileLoader } from '@graphql-tools/code-file-loader'
import { GraphQLFileLoader } from '@graphql-tools/graphql-file-loader'
import { loadDocuments, loadSchemaSync } from '@graphql-tools/load'
import type { LoadTypedefsOptions } from '@graphql-tools/load'
import execa from 'execa'
import { DocumentNode } from 'graphql'

import { getPaths } from '../paths'
Expand Down Expand Up @@ -133,23 +134,49 @@ function getLoadDocumentsOptions(filename: string) {
return loadTypedefsConfig
}

function getPluginConfig() {
let prismaModels: Record<string, string> = {}
try {
// Extract the models from the prisma client and use those to
// set up internal redirects for the return values in resolvers.
const localPrisma = require('@prisma/client')
prismaModels = localPrisma.ModelName
Object.keys(prismaModels).forEach((key) => {
prismaModels[key] = `@prisma/client#${key} as Prisma${key}`
})
// This isn't really something you'd put in the GraphQL API, so
// we can skip the model.
if (prismaModels.RW_DataMigration) {
delete prismaModels.RW_DataMigration
function getPrismaClient(hasGenerated = false): {
ModelName: Record<string, string>
} {
const localPrisma = require('@prisma/client')

if (!localPrisma.ModelName) {
if (hasGenerated) {
return { ModelName: {} }
} else {
execa.sync('yarn rw prisma generate', { shell: true })

// Purge Prisma Client from node's require cache, so that the newly
// generated client gets picked up by any script that uses it
Object.keys(require.cache).forEach((key) => {
if (
key.includes('/node_modules/@prisma/client/') ||
key.includes('/node_modules/.prisma/client/')
) {
delete require.cache[key]
}
})

return getPrismaClient(true)
}
} catch (error) {
// This means they've not set up prisma types yet
}

return localPrisma
}

function getPluginConfig() {
// Extract the models from the prisma client and use those to
// set up internal redirects for the return values in resolvers.
const localPrisma = getPrismaClient()
const prismaModels = localPrisma.ModelName

Object.keys(prismaModels).forEach((key) => {
prismaModels[key] = `@prisma/client#${key} as Prisma${key}`
})

// This isn't really something you'd put in the GraphQL API, so
// we can skip the model.
if (prismaModels.RW_DataMigration) {
delete prismaModels.RW_DataMigration
}

const pluginConfig: CodegenTypes.PluginConfig &
Expand Down

0 comments on commit 0705da1

Please sign in to comment.