Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: output types & list items are now nullable by default #508

Merged
merged 5 commits into from Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/builder.ts
Expand Up @@ -420,7 +420,7 @@ export class SchemaBuilder {
constructor(protected config: BuilderConfig) {
this.nonNullDefaults = {
input: false,
output: true,
output: false,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makes output types nullable by default

...config.nonNullDefaults,
}
this.plugins = config.plugins || [fieldAuthorizePlugin()]
Expand Down Expand Up @@ -1147,7 +1147,7 @@ export class SchemaBuilder {
protected decorateList<T extends GraphQLOutputType | GraphQLInputType>(type: T, list: true | boolean[]): T {
let finalType = type
if (!Array.isArray(list)) {
return GraphQLList(GraphQLNonNull(type)) as T
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bug fix for making list items non-nullable by default

return GraphQLList(type) as T
}
if (Array.isArray(list)) {
for (let i = 0; i < list.length; i++) {
Expand Down
2 changes: 1 addition & 1 deletion src/definitions/_types.ts
Expand Up @@ -72,7 +72,7 @@ export interface NonNullConfig {
* otherField: [String!]!
* }
*
* @default true
* @default false
*/
output?: boolean
/**
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/nullabilityGuardPlugin.ts
Expand Up @@ -59,7 +59,7 @@ const fieldDefTypes = printedGenTyping({
optional: true,
type: 'boolean',
description: `
The nullability guard can be helpful, but is also a pottentially expensive operation for lists.
The nullability guard can be helpful, but is also a potentially expensive operation for lists.
We need to iterate the entire list to check for null items to guard against. Set this to true
to skip the null guard on a specific field if you know there's no potential for unsafe types.
`,
Expand Down
2 changes: 1 addition & 1 deletion tests/__snapshots__/definitions.spec.ts.snap
Expand Up @@ -16,6 +16,6 @@ Array [

exports[`inputObjectType should output lists properly, #33 1`] = `
"input AddToBasketInput {
extras: [ExtraBasketInput!]
extras: [ExtraBasketInput]
}"
`;
2 changes: 1 addition & 1 deletion tests/__snapshots__/makeSchema.spec.ts.snap
Expand Up @@ -7,7 +7,7 @@ exports[`makeSchema shouldExitAfterGenerateArtifacts accepts a customPrintSchema

type Query {
# Example boolean field
ok: Boolean!
ok: Boolean
}
"
`;
16 changes: 8 additions & 8 deletions tests/__snapshots__/plugin.spec.ts.snap
Expand Up @@ -26,26 +26,26 @@ Array [

exports[`plugin has an onMissingType, which will be called in order when we encounter a missing type 1`] = `
"type User {
id: ID!
id: ID
}

type Query {
users: UserConnection!
users: UserConnection
}

type UserConnection {
edges: [UserEdge!]!
connectionInfo: ConnectionInfo!
edges: [UserEdge]
connectionInfo: ConnectionInfo
}

type UserEdge {
cursor: String!
node: User!
cursor: String
node: User
}

type ConnectionInfo {
hasNextPage: Boolean!
hasPrevPage: Boolean!
hasNextPage: Boolean
hasPrevPage: Boolean
}
"
`;
Expand Down
6 changes: 3 additions & 3 deletions tests/__snapshots__/plugins.spec.ts.snap
Expand Up @@ -2,7 +2,7 @@

exports[`onInstall plugins does not have access to inline types 1`] = `
"type Query {
bar(inline: Inline): String!
bar(inline: Inline): String
}

input Inline {
Expand All @@ -20,7 +20,7 @@ exports[`onInstall plugins does not see fallback ok-query 1`] = `

exports[`onInstall plugins has access to top-level types 1`] = `
"type foo {
bar: String!
bar: String
}

type Query {
Expand All @@ -31,7 +31,7 @@ type Query {

exports[`onInstall plugins may contribute types 1`] = `
"type Query {
something: String!
something: String
}
"
`;
Expand Down
2 changes: 1 addition & 1 deletion tests/definitions.spec.ts
Expand Up @@ -142,7 +142,7 @@ describe('objectType', () => {
const typeMap = buildTypes<{ Account: GraphQLObjectType }>([Account])
const fields = typeMap.Account.getFields()
expect(Object.keys(fields).sort()).toEqual(['email', 'id', 'name', 'nestedList'])
expect(fields.nestedList.type.toString()).toEqual('[[String]!]!')
expect(fields.nestedList.type.toString()).toEqual('[[String]!]')
})
})

Expand Down
156 changes: 74 additions & 82 deletions tests/integration/_app.typegen.ts
Expand Up @@ -3,20 +3,20 @@
* Do not make changes to this file directly
*/

import { core } from "../..";
import { core } from '../..'
declare global {
interface NexusGenCustomInputMethods<TypeName extends string> {
title(...args: any): void;
title(...args: any): void
}
}
declare global {
interface NexusGenCustomOutputMethods<TypeName extends string> {
title(options: { escape: boolean }): void;
title(options: { escape: boolean }): void
}
}
declare global {
interface NexusGenCustomOutputProperties<TypeName extends string> {
body: any;
body: any
}
}

Expand All @@ -27,136 +27,128 @@ declare global {
export interface NexusGenInputs {
PostSearchInput: {
// input type
body?: string | null; // String
title?: string | null; // String
};
body?: string | null // String
title?: string | null // String
}
}

export interface NexusGenEnums {}

export interface NexusGenScalars {
String: string;
Int: number;
Float: number;
Boolean: boolean;
ID: string;
String: string
Int: number
Float: number
Boolean: boolean
ID: string
}

export interface NexusGenRootTypes {
Mutation: {};
Mutation: {}
Post: {
// root type
body: string; // String!
title: string; // String!
};
Query: {};
User: { firstName: string; lastName: string };
body?: string | null // String
title?: string | null // String
}
Query: {}
User: { firstName: string; lastName: string }
}

export interface NexusGenAllTypes extends NexusGenRootTypes {
PostSearchInput: NexusGenInputs["PostSearchInput"];
String: NexusGenScalars["String"];
Int: NexusGenScalars["Int"];
Float: NexusGenScalars["Float"];
Boolean: NexusGenScalars["Boolean"];
ID: NexusGenScalars["ID"];
PostSearchInput: NexusGenInputs['PostSearchInput']
String: NexusGenScalars['String']
Int: NexusGenScalars['Int']
Float: NexusGenScalars['Float']
Boolean: NexusGenScalars['Boolean']
ID: NexusGenScalars['ID']
}

export interface NexusGenFieldTypes {
Mutation: {
// field return type
createUser: NexusGenRootTypes["User"]; // User!
};
createUser: NexusGenRootTypes['User'] | null // User
}
Post: {
// field return type
body: string; // String!
title: string; // String!
};
body: string | null // String
title: string | null // String
}
Query: {
// field return type
foo: string; // String!
searchPosts: NexusGenRootTypes["Post"][]; // [Post!]!
user: NexusGenRootTypes["User"]; // User!
};
foo: string | null // String
searchPosts: Array<NexusGenRootTypes['Post'] | null> | null // [Post]
user: NexusGenRootTypes['User'] | null // User
}
User: {
// field return type
firstName: string; // String!
lastName: string; // String!
};
firstName: string | null // String
lastName: string | null // String
}
}

export interface NexusGenArgTypes {
Mutation: {
createUser: {
// args
firstName?: string | null; // String
lastName?: string | null; // String
};
};
firstName?: string | null // String
lastName?: string | null // String
}
}
Query: {
searchPosts: {
// args
input?: NexusGenInputs["PostSearchInput"] | null; // PostSearchInput
};
input?: NexusGenInputs['PostSearchInput'] | null // PostSearchInput
}
user: {
// args
id?: string | null; // ID
};
};
id?: string | null // ID
}
}
}

export interface NexusGenAbstractResolveReturnTypes {}

export interface NexusGenInheritedFields {}

export type NexusGenObjectNames = "Mutation" | "Post" | "Query" | "User";
export type NexusGenObjectNames = 'Mutation' | 'Post' | 'Query' | 'User'

export type NexusGenInputNames = "PostSearchInput";
export type NexusGenInputNames = 'PostSearchInput'

export type NexusGenEnumNames = never;
export type NexusGenEnumNames = never

export type NexusGenInterfaceNames = never;
export type NexusGenInterfaceNames = never

export type NexusGenScalarNames = "Boolean" | "Float" | "ID" | "Int" | "String";
export type NexusGenScalarNames = 'Boolean' | 'Float' | 'ID' | 'Int' | 'String'

export type NexusGenUnionNames = never;
export type NexusGenUnionNames = never

export interface NexusGenTypes {
context: any;
inputTypes: NexusGenInputs;
rootTypes: NexusGenRootTypes;
argTypes: NexusGenArgTypes;
fieldTypes: NexusGenFieldTypes;
allTypes: NexusGenAllTypes;
inheritedFields: NexusGenInheritedFields;
objectNames: NexusGenObjectNames;
inputNames: NexusGenInputNames;
enumNames: NexusGenEnumNames;
interfaceNames: NexusGenInterfaceNames;
scalarNames: NexusGenScalarNames;
unionNames: NexusGenUnionNames;
allInputTypes:
| NexusGenTypes["inputNames"]
| NexusGenTypes["enumNames"]
| NexusGenTypes["scalarNames"];
context: any
inputTypes: NexusGenInputs
rootTypes: NexusGenRootTypes
argTypes: NexusGenArgTypes
fieldTypes: NexusGenFieldTypes
allTypes: NexusGenAllTypes
inheritedFields: NexusGenInheritedFields
objectNames: NexusGenObjectNames
inputNames: NexusGenInputNames
enumNames: NexusGenEnumNames
interfaceNames: NexusGenInterfaceNames
scalarNames: NexusGenScalarNames
unionNames: NexusGenUnionNames
allInputTypes: NexusGenTypes['inputNames'] | NexusGenTypes['enumNames'] | NexusGenTypes['scalarNames']
allOutputTypes:
| NexusGenTypes["objectNames"]
| NexusGenTypes["enumNames"]
| NexusGenTypes["unionNames"]
| NexusGenTypes["interfaceNames"]
| NexusGenTypes["scalarNames"];
allNamedTypes:
| NexusGenTypes["allInputTypes"]
| NexusGenTypes["allOutputTypes"];
abstractTypes: NexusGenTypes["interfaceNames"] | NexusGenTypes["unionNames"];
abstractResolveReturn: NexusGenAbstractResolveReturnTypes;
| NexusGenTypes['objectNames']
| NexusGenTypes['enumNames']
| NexusGenTypes['unionNames']
| NexusGenTypes['interfaceNames']
| NexusGenTypes['scalarNames']
allNamedTypes: NexusGenTypes['allInputTypes'] | NexusGenTypes['allOutputTypes']
abstractTypes: NexusGenTypes['interfaceNames'] | NexusGenTypes['unionNames']
abstractResolveReturn: NexusGenAbstractResolveReturnTypes
}

declare global {
interface NexusGenPluginTypeConfig<TypeName extends string> {}
interface NexusGenPluginFieldConfig<
TypeName extends string,
FieldName extends string
> {}
interface NexusGenPluginFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginSchemaConfig {}
}
4 changes: 2 additions & 2 deletions tests/plugins/__snapshots__/fieldAuthorizePlugin.spec.ts.snap
Expand Up @@ -86,7 +86,7 @@ export interface NexusGenAllTypes extends NexusGenRootTypes {

export interface NexusGenFieldTypes {
Query: { // field return type
ok: boolean; // Boolean!
ok: boolean | null; // Boolean
}
}

Expand Down Expand Up @@ -159,6 +159,6 @@ Array [

exports[`fieldAuthorizePlugin warns when a field has a non-function authorize prop 1`] = `
Array [
[Error: The authorize property provided to incorrectFieldConfig with type User! should be a function, saw number],
[Error: The authorize property provided to incorrectFieldConfig with type User should be a function, saw number],
]
`;
Expand Up @@ -44,7 +44,7 @@ export interface NexusGenAllTypes extends NexusGenRootTypes {

export interface NexusGenFieldTypes {
Query: { // field return type
ok: boolean; // Boolean!
ok: boolean | null; // Boolean
}
}

Expand Down