/
unionType.ts
112 lines (105 loc) · 3.3 KB
/
unionType.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
import { assertValidName, GraphQLUnionTypeConfig } from 'graphql'
import { GetGen } from '../typegenTypeHelpers'
import { NexusObjectTypeDef } from './objectType'
import { AbstractTypes, NexusTypes, SourceTypingDef, withNexusSymbol } from './_types'
export interface UnionDefinitionBuilder {
typeName: string
addUnionMembers(members: UnionMembers): void
}
export type UnionMembers = Array<GetGen<'objectNames'> | NexusObjectTypeDef<any>>
export class UnionDefinitionBlock {
constructor(protected typeBuilder: UnionDefinitionBuilder) {}
/**
* All ObjectType names that should be part of the union, either as string names or as references to the
* `objectType()` return value
*/
members(...unionMembers: UnionMembers) {
this.typeBuilder.addUnionMembers(unionMembers)
}
}
export type NexusUnionTypeConfig<TypeName extends string> = {
/** The name of the union type */
name: TypeName
/** Builds the definition for the union */
definition(t: UnionDefinitionBlock): void
/** The description to annotate the GraphQL SDL */
description?: string
/**
* Info about a field deprecation. Formatted as a string and provided with the deprecated directive on
* field/enum types and as a comment on input fields.
*/
deprecation?: string // | DeprecationInfo;
/** Source type information for this type */
sourceType?: SourceTypingDef
/**
* Custom extensions, as supported in graphql-js
*
* @see https://github.com/graphql/graphql-js/issues/1527
*/
extensions?: GraphQLUnionTypeConfig<any, any>['extensions']
} & AbstractTypes.MaybeTypeDefConfigFieldResolveType<TypeName>
export class NexusUnionTypeDef<TypeName extends string> {
constructor(readonly name: TypeName, protected config: NexusUnionTypeConfig<TypeName>) {
assertValidName(name)
}
get value() {
return this.config
}
}
withNexusSymbol(NexusUnionTypeDef, NexusTypes.Union)
/**
* [API Docs](https://nxs.li/docs/api/union-type) | [Abstract Types
* Guide](https://nxs.li/guides/abstract-types) | [2018 GraphQL Spec](https://spec.graphql.org/June2018/#sec-Unions)
*
* Defines a Union type.
*
* Union types are one of the two abstract type in GraphQL. They let you express polymorphic fields where
* members types can be totally different.
*
* @example
* export const Media = unionType({
* name: 'SearchResult',
* resolveType(source) {
* return 'director' in source ? 'Movie' : 'Song'
* },
* definition(t) {
* t.members('Movie', 'Song')
* },
* })
*
* export const Movie = objectType({
* name: 'Movie',
* definition(t) {
* t.string('url')
* t.string('director')
* },
* })
*
* export const Song = objectType({
* name: 'Song',
* definition(t) {
* t.string('url')
* t.string('album')
* },
* })
*
* // GraphQL SDL
* // -----------
* //
* // union SearchResult = Movie | Song
* //
* // type Movie {
* // director: String
* // url: String
* // }
* //
* // type Song {
* // album: String
* // url: String
* // }
*
* @param config Specify your union's name, its members, and more. See each config property's jsDoc for more detail.
*/
export function unionType<TypeName extends string>(config: NexusUnionTypeConfig<TypeName>) {
return new NexusUnionTypeDef(config.name, config)
}