Skip to content

Commit

Permalink
feat: add .asArg for enum, fix default typings (#708)
Browse files Browse the repository at this point in the history
- Renames `EnumTypeConfig` -> `NexusEnumTypeConfig` for consistency
- Adds `.asArg` on `enumType`, since these are often defined inline for one-off field args
- Fixes types so `default` type is properly inferred, eases types elsewhere so valid types which haven't been added to the manifest do not show as type errors
  • Loading branch information
tgriesser authored Dec 6, 2020
1 parent 439864a commit 9d0f4f4
Show file tree
Hide file tree
Showing 31 changed files with 280 additions and 34 deletions.
7 changes: 5 additions & 2 deletions examples/apollo-fullstack/src/fullstack-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,8 @@ export type NexusGenAbstractsUsingStrategyResolveType = never

export type NexusGenFeaturesConfig = {
abstractTypeStrategies: {
isTypeOf: true
resolveType: false
isTypeOf: false
resolveType: true
__typename: false
}
}
Expand All @@ -224,6 +224,7 @@ export interface NexusGenTypes {
context: t.Context
inputTypes: NexusGenInputs
rootTypes: NexusGenRootTypes
inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars
argTypes: NexusGenArgTypes
fieldTypes: NexusGenFieldTypes
fieldTypeNames: NexusGenFieldTypeNames
Expand Down Expand Up @@ -253,5 +254,7 @@ export interface NexusGenTypes {
declare global {
interface NexusGenPluginTypeConfig<TypeName extends string> {}
interface NexusGenPluginFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginInputFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginSchemaConfig {}
interface NexusGenPluginArgConfig {}
}
7 changes: 5 additions & 2 deletions examples/githunt-api/src/githunt-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,8 +242,8 @@ export type NexusGenAbstractsUsingStrategyResolveType = never

export type NexusGenFeaturesConfig = {
abstractTypeStrategies: {
isTypeOf: true
resolveType: false
isTypeOf: false
resolveType: true
__typename: false
}
}
Expand All @@ -252,6 +252,7 @@ export interface NexusGenTypes {
context: any
inputTypes: NexusGenInputs
rootTypes: NexusGenRootTypes
inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars
argTypes: NexusGenArgTypes
fieldTypes: NexusGenFieldTypes
fieldTypeNames: NexusGenFieldTypeNames
Expand Down Expand Up @@ -281,5 +282,7 @@ export interface NexusGenTypes {
declare global {
interface NexusGenPluginTypeConfig<TypeName extends string> {}
interface NexusGenPluginFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginInputFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginSchemaConfig {}
interface NexusGenPluginArgConfig {}
}
78 changes: 77 additions & 1 deletion examples/kitchen-sink/src/kitchen-sink.gen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ declare global {
interface NexusGenCustomInputMethods<TypeName extends string> {
date<FieldName extends string>(
fieldName: FieldName,
opts?: core.ScalarInputFieldConfig<core.GetGen3<'inputTypes', TypeName, FieldName>>
opts?: core.CommonInputFieldConfig<TypeName, FieldName>
): void // "Date";
}
}
Expand All @@ -18,6 +18,11 @@ declare global {
fieldName: FieldName,
...opts: core.ScalarOutSpread<TypeName, FieldName>
): void // "Date";
/**
* Adds a Relay-style connection to the type, with numerous options for configuration
*
* @see https://nexusjs.org/docs/plugins/connection
*/
connectionField<FieldName extends string>(
fieldName: FieldName,
config: connectionPluginCore.ConnectionFieldConfig<TypeName, FieldName>
Expand Down Expand Up @@ -522,6 +527,7 @@ export interface NexusGenTypes {
context: any
inputTypes: NexusGenInputs
rootTypes: NexusGenRootTypes
inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars
argTypes: NexusGenArgTypes
fieldTypes: NexusGenFieldTypes
fieldTypeNames: NexusGenFieldTypeNames
Expand Down Expand Up @@ -570,6 +576,76 @@ declare global {
* guard on a specific field if you know there's no potential for unsafe types.
*/
skipNullGuard?: boolean
/**
* Whether the type can be null
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
nullable?: boolean
/**
* Whether the type is list of values, or just a single value. If list is true, we assume the type is a
* list. If list is an array, we'll assume that it's a list with the depth. The boolean indicates whether
* the type is required (non-null), where true = nonNull, false = nullable.
*
* @see declarativeWrappingPlugin
*/
list?: true | boolean[]
/**
* Whether the type should be non null, `required: true` = `nullable: false`
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
required?: boolean
}
interface NexusGenPluginInputFieldConfig<TypeName extends string, FieldName extends string> {
/**
* Whether the type can be null
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
nullable?: boolean
/**
* Whether the type is list of values, or just a single value. If list is true, we assume the type is a
* list. If list is an array, we'll assume that it's a list with the depth. The boolean indicates whether
* the type is required (non-null), where true = nonNull, false = nullable.
*
* @see declarativeWrappingPlugin
*/
list?: true | boolean[]
/**
* Whether the type should be non null, `required: true` = `nullable: false`
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
required?: boolean
}
interface NexusGenPluginSchemaConfig {}
interface NexusGenPluginArgConfig {
/**
* Whether the type can be null
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
nullable?: boolean
/**
* Whether the type is list of values, or just a single value. If list is true, we assume the type is a
* list. If list is an array, we'll assume that it's a list with the depth. The boolean indicates whether
* the type is required (non-null), where true = nonNull, false = nullable.
*
* @see declarativeWrappingPlugin
*/
list?: true | boolean[]
/**
* Whether the type should be non null, `required: true` = `nullable: false`
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
required?: boolean
}
}
2 changes: 1 addition & 1 deletion examples/star-wars/src/graphql/character.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const Character = interfaceType({
t.list.field('friends', {
type: 'Character',
description: 'The friends of the character, or an empty list if they have none.',
resolve: (character) => getFriends(character),
resolve: (character) => Promise.all(getFriends(character)),
})
t.list.field('appearsIn', {
type: 'Episode',
Expand Down
71 changes: 71 additions & 0 deletions examples/star-wars/src/star-wars-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ export interface NexusGenTypes {
context: swapi.ContextType
inputTypes: NexusGenInputs
rootTypes: NexusGenRootTypes
inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars
argTypes: NexusGenArgTypes
fieldTypes: NexusGenFieldTypes
fieldTypeNames: NexusGenFieldTypeNames
Expand Down Expand Up @@ -208,6 +209,76 @@ declare global {
* guard on a specific field if you know there's no potential for unsafe types.
*/
skipNullGuard?: boolean
/**
* Whether the type can be null
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
nullable?: boolean
/**
* Whether the type is list of values, or just a single value. If list is true, we assume the type is a
* list. If list is an array, we'll assume that it's a list with the depth. The boolean indicates whether
* the type is required (non-null), where true = nonNull, false = nullable.
*
* @see declarativeWrappingPlugin
*/
list?: true | boolean[]
/**
* Whether the type should be non null, `required: true` = `nullable: false`
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
required?: boolean
}
interface NexusGenPluginInputFieldConfig<TypeName extends string, FieldName extends string> {
/**
* Whether the type can be null
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
nullable?: boolean
/**
* Whether the type is list of values, or just a single value. If list is true, we assume the type is a
* list. If list is an array, we'll assume that it's a list with the depth. The boolean indicates whether
* the type is required (non-null), where true = nonNull, false = nullable.
*
* @see declarativeWrappingPlugin
*/
list?: true | boolean[]
/**
* Whether the type should be non null, `required: true` = `nullable: false`
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
required?: boolean
}
interface NexusGenPluginSchemaConfig {}
interface NexusGenPluginArgConfig {
/**
* Whether the type can be null
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
nullable?: boolean
/**
* Whether the type is list of values, or just a single value. If list is true, we assume the type is a
* list. If list is an array, we'll assume that it's a list with the depth. The boolean indicates whether
* the type is required (non-null), where true = nonNull, false = nullable.
*
* @see declarativeWrappingPlugin
*/
list?: true | boolean[]
/**
* Whether the type should be non null, `required: true` = `nullable: false`
*
* @default (depends on whether nullability is configured in type or schema)
* @see declarativeWrappingPlugin
*/
required?: boolean
}
}
3 changes: 3 additions & 0 deletions examples/ts-ast-reader/src/ts-ast-reader-typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2878,6 +2878,7 @@ export interface NexusGenTypes {
context: t.ContextType
inputTypes: NexusGenInputs
rootTypes: NexusGenRootTypes
inputTypeShapes: NexusGenInputs & NexusGenEnums & NexusGenScalars
argTypes: NexusGenArgTypes
fieldTypes: NexusGenFieldTypes
fieldTypeNames: NexusGenFieldTypeNames
Expand Down Expand Up @@ -2907,5 +2908,7 @@ export interface NexusGenTypes {
declare global {
interface NexusGenPluginTypeConfig<TypeName extends string> {}
interface NexusGenPluginFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginInputFieldConfig<TypeName extends string, FieldName extends string> {}
interface NexusGenPluginSchemaConfig {}
interface NexusGenPluginArgConfig {}
}
5 changes: 3 additions & 2 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
NexusOutputFieldDef,
OutputDefinitionBlock,
} from './definitions/definitionBlocks'
import { EnumTypeConfig } from './definitions/enumType'
import { NexusEnumTypeConfig } from './definitions/enumType'
import { NexusExtendInputTypeConfig, NexusExtendInputTypeDef } from './definitions/extendInputType'
import { NexusExtendTypeConfig, NexusExtendTypeDef } from './definitions/extendType'
import { NexusInputObjectTypeConfig } from './definitions/inputObjectType'
Expand Down Expand Up @@ -555,6 +555,7 @@ export class SchemaBuilder {
}
if (isSchema(types)) {
this.addTypes(types.getTypeMap())
return
}
if (isNexusPlugin(types)) {
if (!this.plugins?.includes(types)) {
Expand Down Expand Up @@ -949,7 +950,7 @@ export class SchemaBuilder {
return field
}

private buildEnumType(config: EnumTypeConfig<any>) {
private buildEnumType(config: NexusEnumTypeConfig<any>) {
const { members } = config
const values: GraphQLEnumValueConfigMap = {}
if (Array.isArray(members)) {
Expand Down
36 changes: 27 additions & 9 deletions src/definitions/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,37 @@ export type CommonArgConfig = {
} & NexusGenPluginArgConfig

export interface ScalarArgConfig<T> extends CommonArgConfig {
/** Configure the default for the object */
/**
* Configure the default for the object
*
* @example
* intArg({ default: 42 })
*/
default?: T
}

export type NexusArgConfigType<T extends AllInputTypes> = T | AllNexusInputTypeDefs<T>
export type NexusArgConfigType<T extends string> = T | AllNexusInputTypeDefs<T>

export interface NexusAsArgConfig<T extends AllInputTypes> extends CommonArgConfig {
/** Configure the default for the object */
default?: GetGen2<'allTypes', T> // TODO: Make this type-safe somehow
export interface NexusAsArgConfig<T extends string> extends CommonArgConfig {
/**
* Sets the default value for this argument, should match the type of the argument
*
* @example
* intArg({ default: 42 })
*/
default?: GetGen2<'inputTypeShapes', T>
}

export interface NexusArgConfig<T extends AllInputTypes> extends NexusAsArgConfig<T> {
/** The type of the argument, either the string name of the type, or the concrete Nexus type definition */
export interface NexusArgConfig<T extends string> extends NexusAsArgConfig<T> {
/**
* The type of the argument, either the string name of the type, or the concrete Nexus type definition
*
* @example
* arg({ type: 'User' })
*
* @example
* arg({ type: UserType })
*/
type: NexusArgConfigType<T>
}

Expand All @@ -34,7 +52,7 @@ export interface NexusFinalArgConfig extends NexusArgConfig<any> {
}

export class NexusArgDef<TypeName extends AllInputTypes> {
constructor(readonly name: string, protected config: NexusArgConfig<TypeName>) {}
constructor(readonly name: TypeName, protected config: NexusArgConfig<any>) {}
get value() {
return this.config
}
Expand All @@ -50,7 +68,7 @@ withNexusSymbol(NexusArgDef, NexusTypes.Arg)
*
* @see https://graphql.github.io/learn/schema/#arguments
*/
export function arg<T extends AllInputTypes>(options: NexusArgConfig<T>) {
export function arg<T extends string>(options: NexusArgConfig<T>) {
if (!options.type) {
throw new Error('You must provide a "type" for the arg()')
}
Expand Down
2 changes: 1 addition & 1 deletion src/definitions/definitionBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class OutputDefinitionBlock<TypeName extends string> {

export interface NexusInputFieldConfig<TypeName extends string, FieldName extends string>
extends CommonInputFieldConfig<TypeName, FieldName> {
type: AllInputTypes | AllNexusInputTypeDefs<string>
type: AllInputTypes | AllNexusInputTypeDefs
}

export type NexusInputFieldDef = NexusInputFieldConfig<string, string> & {
Expand Down
Loading

0 comments on commit 9d0f4f4

Please sign in to comment.