diff --git a/src/handlers/input-type.ts b/src/handlers/input-type.ts index 4799bfb6..dac08987 100644 --- a/src/handlers/input-type.ts +++ b/src/handlers/input-type.ts @@ -101,49 +101,57 @@ export function inputType( propertyType, isList, }); - classStructure.properties?.push(property); + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + classStructure.properties!.push(property); if (propertySettings) { importDeclarations.create({ ...propertySettings }); } - if (settings?.shouldHideField({ name: inputType.name, input: true })) { - importDeclarations.add('HideField', '@nestjs/graphql'); - property.decorators?.push({ name: 'HideField', arguments: [] }); - } else { - ok(property.decorators); + // Get graphql type + let graphqlType: string; + const shouldHideField = settings?.shouldHideField({ + name: inputType.name, + input: true, + }); + const fieldType = settings?.getFieldType({ + name: inputType.name, + input: true, + }); - let graphqlType: string; - const fieldType = settings?.getFieldType({ - name: inputType.name, - input: true, + if (fieldType && isCustomsApplicable && !shouldHideField) { + graphqlType = fieldType.name; + importDeclarations.create({ ...fieldType }); + } else { + // Import property type class + const graphqlImport = getGraphqlImport({ + sourceFile, + location, + typeName, + getSourceFile, }); - if (fieldType && isCustomsApplicable) { - graphqlType = fieldType.name; - importDeclarations.create({ ...fieldType }); - } else { - const graphqlImport = getGraphqlImport({ - sourceFile, - location, - typeName, - getSourceFile, + graphqlType = graphqlImport.name; + + if ( + graphqlImport.specifier && + !importDeclarations.has(graphqlImport.name) && + ((graphqlImport.name !== inputType.name && !shouldHideField) || + (shouldHideField && propertyType[0] === graphqlImport.name)) + ) { + importDeclarations.set(graphqlImport.name, { + namedImports: [{ name: graphqlImport.name }], + moduleSpecifier: graphqlImport.specifier, }); - - graphqlType = graphqlImport.name; - - if ( - graphqlImport.name !== inputType.name && - graphqlImport.specifier && - !importDeclarations.has(graphqlImport.name) - ) { - importDeclarations.set(graphqlImport.name, { - namedImports: [{ name: graphqlImport.name }], - moduleSpecifier: graphqlImport.specifier, - }); - } } + } + + ok(property.decorators, 'property.decorators is undefined'); + if (shouldHideField) { + importDeclarations.add('HideField', '@nestjs/graphql'); + property.decorators.push({ name: 'HideField', arguments: [] }); + } else { // Generate `@Field()` decorator property.decorators.push({ name: 'Field', diff --git a/src/handlers/output-type.ts b/src/handlers/output-type.ts index cfc45a82..dca03c5a 100644 --- a/src/handlers/output-type.ts +++ b/src/handlers/output-type.ts @@ -89,45 +89,51 @@ export function outputType(outputType: OutputType, args: EventArguments) { importDeclarations.create({ ...propertySettings }); } - ok(property.decorators, 'property.decorators is undefined'); + // Get graphql type + let graphqlType: string; + const shouldHideField = settings?.shouldHideField({ + name: outputType.name, + output: true, + }); + const fieldType = settings?.getFieldType({ + name: outputType.name, + output: true, + }); - if (settings?.shouldHideField({ name: outputType.name, output: true })) { - importDeclarations.add('HideField', nestjsGraphql); - property.decorators.push({ name: 'HideField', arguments: [] }); + if (fieldType && isCustomsApplicable && !shouldHideField) { + graphqlType = fieldType.name; + importDeclarations.create({ ...fieldType }); } else { - let graphqlType: string; - const fieldType = settings?.getFieldType({ - name: outputType.name, - output: true, + const graphqlImport = getGraphqlImport({ + sourceFile, + fileType, + location, + isId: false, + typeName: outputTypeName, + getSourceFile, }); - if (fieldType && isCustomsApplicable) { - graphqlType = fieldType.name; - importDeclarations.create({ ...fieldType }); - } else { - const graphqlImport = getGraphqlImport({ - sourceFile, - fileType, - location, - isId: false, - typeName: outputTypeName, - getSourceFile, + graphqlType = graphqlImport.name; + + if ( + graphqlImport.specifier && + !importDeclarations.has(graphqlImport.name) && + ((graphqlImport.name !== outputType.name && !shouldHideField) || + (shouldHideField && propertyType[0] === graphqlImport.name)) + ) { + importDeclarations.set(graphqlImport.name, { + namedImports: [{ name: graphqlImport.name }], + moduleSpecifier: graphqlImport.specifier, }); - - graphqlType = graphqlImport.name; - - if ( - graphqlImport.name !== outputType.name && - graphqlImport.specifier && - !importDeclarations.has(graphqlImport.name) - ) { - importDeclarations.set(graphqlImport.name, { - namedImports: [{ name: graphqlImport.name }], - moduleSpecifier: graphqlImport.specifier, - }); - } } + } + ok(property.decorators, 'property.decorators is undefined'); + + if (shouldHideField) { + importDeclarations.add('HideField', nestjsGraphql); + property.decorators.push({ name: 'HideField', arguments: [] }); + } else { // Generate `@Field()` decorator property.decorators.push({ name: 'Field', diff --git a/src/helpers/generate-import.ts b/src/helpers/generate-import.ts deleted file mode 100644 index 22d9415b..00000000 --- a/src/helpers/generate-import.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { SourceFile } from 'ts-morph'; - -export function generateImport(args: { - name: string; - sourceFile: SourceFile; - moduleSpecifier: string | undefined; -}) { - const { moduleSpecifier, name, sourceFile } = args; - if (!moduleSpecifier) { - return name; - } - let importDeclaration = sourceFile.getImportDeclaration( - importDeclaration => - importDeclaration.getModuleSpecifier().getLiteralValue() === - moduleSpecifier, - ); - if (!importDeclaration) { - importDeclaration = sourceFile.addImportDeclaration({ - moduleSpecifier, - }); - } - let importSpecifier = importDeclaration - .getNamedImports() - .find(importSpecifier => importSpecifier.getName() === name); - - if (!importSpecifier) { - importSpecifier = importDeclaration.addNamedImport({ - name, - }); - } - - return importSpecifier.getName(); -} diff --git a/src/test/generate.spec.ts b/src/test/generate.spec.ts index 08ba6191..45bb5d58 100644 --- a/src/test/generate.spec.ts +++ b/src/test/generate.spec.ts @@ -1406,6 +1406,31 @@ describe('hide field', () => { ); }); }); + + it('hidden relations result in un-imported types', async () => { + ({ project, sourceFiles } = await testGenerate({ + schema: ` + model User { + id String @id @default(uuid()) + userApiKey UserApiKey[] + } + + model UserApiKey { + id String @id @default(uuid()) + userId String + /// @HideField({ input: true }) + user User @relation(fields: [userId], references: [id]) + } + `, + options: [`outputFilePattern = "{name}.{type}.ts"`], + })); + setSourceFile('user-api-key-where.input.ts'); + expect(p('user')?.type).toEqual('UserRelationFilter'); + expect(imports).toContainEqual({ + name: 'UserRelationFilter', + specifier: './user-relation-filter.input', + }); + }); }); it('model with prisma keyword output', async () => { @@ -2167,7 +2192,6 @@ describe('property type', () => { it('user-create.input', () => { setSourceFile('user-create.input.ts'); expect(p('profile')?.type).toEqual('JsonObject'); - }); it('should use default scalar type in user-update-many-mutation.input', () => { @@ -2182,9 +2206,10 @@ describe('property type', () => { }); }); -it('hidefield on groupby', async () => { - ({ project, sourceFiles } = await testGenerate({ - schema: ` +describe('hidefield on groupby output', () => { + before(async () => { + ({ project, sourceFiles } = await testGenerate({ + schema: ` model User { id Int @id /// @HideField({ match: '*GroupBy' }) @@ -2193,19 +2218,26 @@ it('hidefield on groupby', async () => { profile Json } `, - options: [`outputFilePattern = "{name}.{type}.ts"`], - })); - setSourceFile('user-group-by.output.ts'); - expect(imports).not.toContainEqual( - expect.objectContaining({ - name: 'GraphQLJSONObject', - }), - ); - expect(imports).not.toContainEqual( - expect.objectContaining({ - name: 'GraphQLJSON', - }), - ); + options: [`outputFilePattern = "{name}.{type}.ts"`], + })); + setSourceFile('user-group-by.output.ts'); + }); + + it('no graphqljsonobject', () => { + expect(imports).not.toContainEqual( + expect.objectContaining({ + name: 'GraphQLJSONObject', + }), + ); + }); + + it('no graphqljson', () => { + expect(imports).not.toContainEqual( + expect.objectContaining({ + name: 'GraphQLJSON', + }), + ); + }); }); describe('non list optional properties should be nullable', () => {