1 | import type { GraphQLEnumValue, GraphQLError, GraphQLField, GraphQLInputField, GraphQLSchema } from 'graphql'
|
2 | import {
|
3 | GraphQLEnumType,
|
4 | GraphQLInputObjectType,
|
5 | GraphQLInterfaceType,
|
6 | GraphQLList,
|
7 | GraphQLNonNull,
|
8 | GraphQLObjectType,
|
9 | GraphQLScalarType,
|
10 | GraphQLUnionType,
|
11 | isListType,
|
12 | isNonNullType,
|
13 | } from 'graphql'
|
14 | import type { ObjMap } from 'graphql/jsutils/ObjMap.js'
|
15 | import type { Errors } from './errors/__.js'
|
16 |
|
17 | export type TypeMapByKind =
|
18 | & {
|
19 | [Name in keyof NameToClassNamedType]: InstanceType<NameToClassNamedType[Name]>[]
|
20 | }
|
21 | & { GraphQLRootType: GraphQLObjectType[] }
|
22 | & { GraphQLScalarTypeCustom: GraphQLScalarType<any, any>[] }
|
23 | & { GraphQLScalarTypeStandard: GraphQLScalarType<any, any>[] }
|
24 |
|
25 | export const standardScalarTypeNames = {
|
26 | String: `String`,
|
27 | ID: `ID`,
|
28 | Int: `Int`,
|
29 | Float: `Float`,
|
30 | Boolean: `Boolean`,
|
31 | }
|
32 |
|
33 | export const RootTypeName = {
|
34 | Query: `Query`,
|
35 | Mutation: `Mutation`,
|
36 | Subscription: `Subscription`,
|
37 | } as const
|
38 |
|
39 | export const operationTypeNameToRootTypeName = {
|
40 | query: `Query`,
|
41 | mutation: `Mutation`,
|
42 | subscription: `Subscription`,
|
43 | } as const
|
44 |
|
45 | export const rootTypeNameToOperationName = {
|
46 | Query: `query`,
|
47 | Mutation: `mutation`,
|
48 | Subscription: `subscription`,
|
49 | } as const
|
50 |
|
51 | export type RootTypeName = keyof typeof RootTypeName
|
52 |
|
53 | export const isStandardScalarType = (type: GraphQLScalarType) => {
|
54 | return type.name in standardScalarTypeNames
|
55 | }
|
56 |
|
57 | export const isCustomScalarType = (type: GraphQLScalarType) => {
|
58 | return !isStandardScalarType(type)
|
59 | }
|
60 |
|
61 | export const unwrapToNamed = (
|
62 | type: AnyClass,
|
63 | ): AnyClass => {
|
64 | if (isNonNullType(type)) return unwrapToNamed(unwrapToNonNull(type).ofType)
|
65 | if (isListType(type)) return unwrapToNamed(type.ofType)
|
66 | return type
|
67 | }
|
68 |
|
69 | export const unwrapToNonNull = (
|
70 | type: AnyClass,
|
71 | ): { ofType: AnyClass; nullable: boolean } => {
|
72 | const [nodeUnwrapped, nullable] = type instanceof GraphQLNonNull ? [type.ofType, false] : [type, true]
|
73 | return { ofType: nodeUnwrapped, nullable }
|
74 | }
|
75 |
|
76 | export const getTypeMapByKind = (schema: GraphQLSchema) => {
|
77 | const typeMap = schema.getTypeMap()
|
78 | const typeMapValues = Object.values(typeMap)
|
79 | const typeMapByKind: TypeMapByKind = {
|
80 | GraphQLRootType: [],
|
81 | GraphQLScalarType: [],
|
82 | GraphQLScalarTypeCustom: [],
|
83 | GraphQLScalarTypeStandard: [],
|
84 | GraphQLEnumType: [],
|
85 | GraphQLInputObjectType: [],
|
86 | GraphQLInterfaceType: [],
|
87 | GraphQLObjectType: [],
|
88 | GraphQLUnionType: [],
|
89 | }
|
90 | for (const type of typeMapValues) {
|
91 | if (type.name.startsWith(`__`)) continue
|
92 | switch (true) {
|
93 | case type instanceof GraphQLScalarType:
|
94 | typeMapByKind.GraphQLScalarType.push(type)
|
95 | if (isCustomScalarType(type)) {
|
96 | typeMapByKind.GraphQLScalarTypeCustom.push(type)
|
97 | } else {
|
98 | typeMapByKind.GraphQLScalarTypeStandard.push(type)
|
99 | }
|
100 | break
|
101 | case type instanceof GraphQLEnumType:
|
102 | typeMapByKind.GraphQLEnumType.push(type)
|
103 | break
|
104 | case type instanceof GraphQLInputObjectType:
|
105 | typeMapByKind.GraphQLInputObjectType.push(type)
|
106 | break
|
107 | case type instanceof GraphQLInterfaceType:
|
108 | typeMapByKind.GraphQLInterfaceType.push(type)
|
109 | break
|
110 | case type instanceof GraphQLObjectType:
|
111 | if (type.name === `Query` || type.name === `Mutation` || type.name === `Subscription`) {
|
112 | typeMapByKind.GraphQLRootType.push(type)
|
113 | } else {
|
114 | typeMapByKind.GraphQLObjectType.push(type)
|
115 | }
|
116 | break
|
117 | case type instanceof GraphQLUnionType:
|
118 | typeMapByKind.GraphQLUnionType.push(type)
|
119 | break
|
120 | default:
|
121 |
|
122 | break
|
123 | }
|
124 | }
|
125 | return typeMapByKind
|
126 | }
|
127 |
|
128 | export type ClassToName<C> = C extends GraphQLScalarType ? `GraphQLScalarType`
|
129 | : C extends GraphQLObjectType ? `GraphQLObjectType`
|
130 | : C extends GraphQLInterfaceType ? `GraphQLInterfaceType`
|
131 | : C extends GraphQLUnionType ? `GraphQLUnionType`
|
132 | : C extends GraphQLEnumType ? `GraphQLEnumType`
|
133 | : C extends GraphQLInputObjectType ? `GraphQLInputObjectType`
|
134 | : C extends GraphQLList<any> ? `GraphQLList`
|
135 | : C extends GraphQLNonNull<any> ? `GraphQLNonNull`
|
136 | : never
|
137 |
|
138 | export const NameToClassNamedType = {
|
139 | GraphQLScalarType: GraphQLScalarType,
|
140 | GraphQLObjectType: GraphQLObjectType,
|
141 | GraphQLInterfaceType: GraphQLInterfaceType,
|
142 | GraphQLUnionType: GraphQLUnionType,
|
143 | GraphQLEnumType: GraphQLEnumType,
|
144 | GraphQLInputObjectType: GraphQLInputObjectType,
|
145 | }
|
146 |
|
147 | export type NameToClassNamedType = typeof NameToClassNamedType
|
148 |
|
149 | export const NamedNameToClass = {
|
150 | GraphQLScalarType: GraphQLScalarType,
|
151 | GraphQLObjectType: GraphQLObjectType,
|
152 | GraphQLInterfaceType: GraphQLInterfaceType,
|
153 | GraphQLUnionType: GraphQLUnionType,
|
154 | GraphQLEnumType: GraphQLEnumType,
|
155 | GraphQLInputObjectType: GraphQLInputObjectType,
|
156 | } as const
|
157 |
|
158 | export type NamedNameToClass = typeof NamedNameToClass
|
159 |
|
160 | export const NameToClass = {
|
161 | GraphQLNonNull: GraphQLNonNull,
|
162 | GraphQLList: GraphQLList,
|
163 | ...NamedNameToClass,
|
164 | } as const
|
165 |
|
166 | export type AnyGraphQLOutputField = GraphQLField<any, any>
|
167 |
|
168 | export type AnyField = AnyGraphQLOutputField | GraphQLInputField
|
169 |
|
170 | export type NameToClass = typeof NameToClass
|
171 |
|
172 | export type NodeName = keyof NameToClass
|
173 |
|
174 | export type NodeNamePlus = NodeName | 'GraphQLField'
|
175 |
|
176 | export type AnyNamedClassName = keyof NamedNameToClass
|
177 |
|
178 | export type AnyClass = InstanceType<NameToClass[keyof NameToClass]>
|
179 |
|
180 | export const isGraphQLOutputField = (object: object): object is AnyGraphQLOutputField => {
|
181 | return `args` in object
|
182 | }
|
183 |
|
184 |
|
185 |
|
186 |
|
187 |
|
188 | export type Describable =
|
189 | | GraphQLUnionType
|
190 | | GraphQLObjectType
|
191 | | GraphQLInputObjectType
|
192 | | AnyField
|
193 | | GraphQLInterfaceType
|
194 | | GraphQLEnumType
|
195 |
|
196 | export const getNodeName = (node: Describable): NodeNamePlus => {
|
197 | switch (true) {
|
198 | case node instanceof GraphQLObjectType:
|
199 | return `GraphQLObjectType`
|
200 | case node instanceof GraphQLInputObjectType:
|
201 | return `GraphQLInputObjectType`
|
202 | case node instanceof GraphQLUnionType:
|
203 | return `GraphQLUnionType`
|
204 | case node instanceof GraphQLInterfaceType:
|
205 | return `GraphQLInterfaceType`
|
206 | case node instanceof GraphQLEnumType:
|
207 | return `GraphQLEnumType`
|
208 | case node instanceof GraphQLScalarType:
|
209 | return `GraphQLScalarType`
|
210 | default:
|
211 | return `GraphQLField`
|
212 | }
|
213 | }
|
214 |
|
215 |
|
216 |
|
217 |
|
218 |
|
219 |
|
220 |
|
221 |
|
222 |
|
223 |
|
224 |
|
225 |
|
226 | export const getNodeDisplayName = (node: Describable) => {
|
227 | return toDisplayName(getNodeName(node))
|
228 | }
|
229 |
|
230 | const toDisplayName = (nodeName: NodeNamePlus) => {
|
231 | return nodeName.replace(/^GraphQL/, ``).replace(/Type$/, ``)
|
232 | }
|
233 |
|
234 | export const isDeprecatableNode = (node: object): node is GraphQLEnumValue | AnyField => {
|
235 | return `deprecationReason` in node
|
236 | }
|
237 |
|
238 | export const hasQuery = (typeMapByKind: TypeMapByKind) => typeMapByKind.GraphQLRootType.find((_) => _.name === `Query`)
|
239 |
|
240 | export const hasMutation = (typeMapByKind: TypeMapByKind) =>
|
241 | typeMapByKind.GraphQLRootType.find((_) => _.name === `Mutation`)
|
242 |
|
243 | export const hasSubscription = (typeMapByKind: TypeMapByKind) =>
|
244 | typeMapByKind.GraphQLRootType.find((_) => _.name === `Subscription`)
|
245 |
|
246 | export type StandardScalarVariables = {
|
247 | [key: string]: string | boolean | null | number | StandardScalarVariables
|
248 | }
|
249 |
|
250 | export type GraphQLExecutionResultError = Errors.ContextualAggregateError<GraphQLError>
|
251 |
|
252 | export type OperationTypeName = 'query' | 'mutation'
|
253 |
|
254 | export const isOperationTypeName = (value: unknown): value is OperationTypeName =>
|
255 | value === `query` || value === `mutation`
|
256 |
|
257 | export interface SomeExecutionResultWithoutErrors<
|
258 | TData = ObjMap<unknown>,
|
259 | TExtensions = ObjMap<unknown>,
|
260 | > {
|
261 | errors?: readonly []
|
262 | data?: TData | null
|
263 | extensions?: TExtensions
|
264 | }
|