@gqlkit-ts/runtime 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -2
- package/src/index.ts +764 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gqlkit-ts/runtime",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Runtime utilities for gqlkit - type-safe resolver definition functions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"files": [
|
|
15
|
-
"dist"
|
|
15
|
+
"dist",
|
|
16
|
+
"src"
|
|
16
17
|
],
|
|
17
18
|
"keywords": [
|
|
18
19
|
"graphql",
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,764 @@
|
|
|
1
|
+
import type { GraphQLResolveInfo } from "graphql";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Represents the locations where a directive can be applied.
|
|
5
|
+
* This corresponds to GraphQL Type System Directive Locations.
|
|
6
|
+
*/
|
|
7
|
+
export type DirectiveLocation =
|
|
8
|
+
| "SCHEMA"
|
|
9
|
+
| "SCALAR"
|
|
10
|
+
| "OBJECT"
|
|
11
|
+
| "FIELD_DEFINITION"
|
|
12
|
+
| "ARGUMENT_DEFINITION"
|
|
13
|
+
| "INTERFACE"
|
|
14
|
+
| "UNION"
|
|
15
|
+
| "ENUM"
|
|
16
|
+
| "ENUM_VALUE"
|
|
17
|
+
| "INPUT_OBJECT"
|
|
18
|
+
| "INPUT_FIELD_DEFINITION";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Represents a GraphQL directive with name, arguments, and location.
|
|
22
|
+
* Used to define custom directives that can be attached to types and fields.
|
|
23
|
+
*
|
|
24
|
+
* @typeParam Name - The directive name (without @)
|
|
25
|
+
* @typeParam Args - The argument types for the directive
|
|
26
|
+
* @typeParam Location - The location(s) where the directive can be applied
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* type AuthDirective<R extends string[]> = GqlDirective<"auth", { roles: R }, "FIELD_DEFINITION">;
|
|
31
|
+
* type CacheDirective = GqlDirective<"cache", { maxAge: number }, "FIELD_DEFINITION" | "OBJECT">;
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export type GqlDirective<
|
|
35
|
+
Name extends string,
|
|
36
|
+
Args extends Record<string, unknown> = Record<string, never>,
|
|
37
|
+
Location extends DirectiveLocation | DirectiveLocation[] = DirectiveLocation,
|
|
38
|
+
> = {
|
|
39
|
+
readonly " $directiveName": Name;
|
|
40
|
+
readonly " $directiveArgs": Args;
|
|
41
|
+
readonly " $directiveLocation": Location;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Metadata structure for field-level GraphQL metadata.
|
|
46
|
+
* Used to attach directives, default values, and other metadata to individual fields.
|
|
47
|
+
*
|
|
48
|
+
* @typeParam Meta - The metadata configuration object
|
|
49
|
+
*/
|
|
50
|
+
export interface GqlFieldMetaShape<
|
|
51
|
+
Meta extends {
|
|
52
|
+
directives?: ReadonlyArray<
|
|
53
|
+
GqlDirective<
|
|
54
|
+
string,
|
|
55
|
+
Record<string, unknown>,
|
|
56
|
+
DirectiveLocation | DirectiveLocation[]
|
|
57
|
+
>
|
|
58
|
+
>;
|
|
59
|
+
defaultValue?: unknown;
|
|
60
|
+
},
|
|
61
|
+
> {
|
|
62
|
+
readonly directives?: Meta["directives"];
|
|
63
|
+
readonly defaultValue?: Meta["defaultValue"];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Attaches metadata to a field type.
|
|
68
|
+
* The metadata is embedded as optional properties to maintain compatibility
|
|
69
|
+
* with the underlying type.
|
|
70
|
+
*
|
|
71
|
+
* The structure uses two properties:
|
|
72
|
+
* - `$gqlkitFieldMeta`: Contains the metadata object with directives and defaultValue
|
|
73
|
+
* - `$gqlkitOriginalType`: Preserves the original type T to maintain nullability information
|
|
74
|
+
*
|
|
75
|
+
* This design is necessary because TypeScript normalizes `(T | null) & { metadata }` to
|
|
76
|
+
* `(T & { metadata }) | never`, which loses the null part of the union. By storing
|
|
77
|
+
* the original type in `$gqlkitOriginalType`, we can recover the full type information
|
|
78
|
+
* during CLI analysis.
|
|
79
|
+
*
|
|
80
|
+
* @typeParam T - The base type to attach metadata to
|
|
81
|
+
* @typeParam Meta - The metadata configuration object containing directives and/or defaultValue
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* // With directives
|
|
86
|
+
* type User = {
|
|
87
|
+
* id: GqlField<IDString, { directives: [AuthDirective<{ role: ["USER"] }>] }>;
|
|
88
|
+
* bio: GqlField<string | null, { directives: [AuthDirective<{ role: ["ADMIN"] }>] }>;
|
|
89
|
+
* };
|
|
90
|
+
*
|
|
91
|
+
* // With default value
|
|
92
|
+
* type PaginationInput = {
|
|
93
|
+
* limit: GqlField<Int, { defaultValue: 10 }>;
|
|
94
|
+
* offset: GqlField<Int, { defaultValue: 0 }>;
|
|
95
|
+
* };
|
|
96
|
+
*
|
|
97
|
+
* // With both directives and default value
|
|
98
|
+
* type SearchInput = {
|
|
99
|
+
* query: GqlField<string, { defaultValue: ""; directives: [SomeDirective] }>;
|
|
100
|
+
* };
|
|
101
|
+
* ```
|
|
102
|
+
*/
|
|
103
|
+
export type GqlField<
|
|
104
|
+
T,
|
|
105
|
+
Meta extends {
|
|
106
|
+
directives?: ReadonlyArray<
|
|
107
|
+
GqlDirective<
|
|
108
|
+
string,
|
|
109
|
+
Record<string, unknown>,
|
|
110
|
+
DirectiveLocation | DirectiveLocation[]
|
|
111
|
+
>
|
|
112
|
+
>;
|
|
113
|
+
defaultValue?: unknown;
|
|
114
|
+
} = object,
|
|
115
|
+
> = T & {
|
|
116
|
+
readonly " $gqlkitFieldMeta"?: GqlFieldMetaShape<Meta>;
|
|
117
|
+
readonly " $gqlkitOriginalType"?: T;
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Marker type for GqlInterface - used internally for type discrimination.
|
|
122
|
+
*/
|
|
123
|
+
export type GqlInterfaceMarker = Record<string, unknown>;
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Interface metadata structure embedded in intersection types.
|
|
127
|
+
* Used by CLI to detect and identify interface types through type analysis.
|
|
128
|
+
*
|
|
129
|
+
* @typeParam Meta - The metadata configuration object containing implements
|
|
130
|
+
*/
|
|
131
|
+
export interface GqlInterfaceMetaShape<
|
|
132
|
+
Meta extends {
|
|
133
|
+
implements?: ReadonlyArray<GqlInterfaceMarker>;
|
|
134
|
+
} = object,
|
|
135
|
+
> {
|
|
136
|
+
readonly " $gqlkitInterface": true;
|
|
137
|
+
readonly implements?: Meta["implements"];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* GraphQL interface type definition utility.
|
|
142
|
+
* Use this to define GraphQL interface types that can be implemented by object types.
|
|
143
|
+
*
|
|
144
|
+
* @typeParam T - The interface field definitions as an object type
|
|
145
|
+
* @typeParam Meta - Optional metadata containing implements for interface inheritance
|
|
146
|
+
*
|
|
147
|
+
* @example
|
|
148
|
+
* ```typescript
|
|
149
|
+
* // Basic interface definition
|
|
150
|
+
* export type Node = GqlInterface<{
|
|
151
|
+
* id: IDString;
|
|
152
|
+
* }>;
|
|
153
|
+
*
|
|
154
|
+
* export type Timestamped = GqlInterface<{
|
|
155
|
+
* createdAt: DateTime;
|
|
156
|
+
* updatedAt: DateTime;
|
|
157
|
+
* }>;
|
|
158
|
+
*
|
|
159
|
+
* // Interface inheriting other interfaces
|
|
160
|
+
* export type Entity = GqlInterface<
|
|
161
|
+
* {
|
|
162
|
+
* id: IDString;
|
|
163
|
+
* createdAt: DateTime;
|
|
164
|
+
* updatedAt: DateTime;
|
|
165
|
+
* },
|
|
166
|
+
* { implements: [Node, Timestamped] }
|
|
167
|
+
* >;
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export type GqlInterface<
|
|
171
|
+
T extends Record<string, unknown>,
|
|
172
|
+
Meta extends {
|
|
173
|
+
implements?: ReadonlyArray<GqlInterfaceMarker>;
|
|
174
|
+
} = object,
|
|
175
|
+
> = T & {
|
|
176
|
+
readonly " $gqlkitInterfaceMeta"?: GqlInterfaceMetaShape<Meta>;
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Metadata structure for type-level GraphQL metadata.
|
|
181
|
+
* Used to attach directives and other metadata to types.
|
|
182
|
+
*
|
|
183
|
+
* @typeParam Meta - The metadata configuration object
|
|
184
|
+
*/
|
|
185
|
+
export interface GqlTypeMetaShape<
|
|
186
|
+
Meta extends {
|
|
187
|
+
directives?: ReadonlyArray<
|
|
188
|
+
GqlDirective<
|
|
189
|
+
string,
|
|
190
|
+
Record<string, unknown>,
|
|
191
|
+
DirectiveLocation | DirectiveLocation[]
|
|
192
|
+
>
|
|
193
|
+
>;
|
|
194
|
+
implements?: ReadonlyArray<GqlInterfaceMarker>;
|
|
195
|
+
},
|
|
196
|
+
> {
|
|
197
|
+
readonly directives?: Meta["directives"];
|
|
198
|
+
readonly implements?: Meta["implements"];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Attaches metadata to a type definition.
|
|
203
|
+
* The metadata is embedded as optional properties to maintain compatibility
|
|
204
|
+
* with the underlying type.
|
|
205
|
+
*
|
|
206
|
+
* The structure uses two properties:
|
|
207
|
+
* - `$gqlkitTypeMeta`: Contains the metadata object with directives and implements
|
|
208
|
+
* - `$gqlkitOriginalType`: Preserves the original type T to maintain nullability information
|
|
209
|
+
*
|
|
210
|
+
* @typeParam T - The base type to attach metadata to
|
|
211
|
+
* @typeParam Meta - The metadata configuration object containing directives and/or implements
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* // Type with directives only
|
|
216
|
+
* type User = GqlObject<
|
|
217
|
+
* {
|
|
218
|
+
* id: string;
|
|
219
|
+
* name: string;
|
|
220
|
+
* },
|
|
221
|
+
* { directives: [CacheDirective<{ maxAge: 60 }>] }
|
|
222
|
+
* >;
|
|
223
|
+
*
|
|
224
|
+
* // Type implementing an interface
|
|
225
|
+
* type User = GqlObject<
|
|
226
|
+
* {
|
|
227
|
+
* id: IDString;
|
|
228
|
+
* name: string;
|
|
229
|
+
* },
|
|
230
|
+
* { implements: [Node] }
|
|
231
|
+
* >;
|
|
232
|
+
*
|
|
233
|
+
* // Type with both directives and implements
|
|
234
|
+
* type Post = GqlObject<
|
|
235
|
+
* {
|
|
236
|
+
* id: IDString;
|
|
237
|
+
* title: string;
|
|
238
|
+
* createdAt: DateTime;
|
|
239
|
+
* },
|
|
240
|
+
* {
|
|
241
|
+
* implements: [Node, Timestamped],
|
|
242
|
+
* directives: [CacheDirective<{ maxAge: 60 }>]
|
|
243
|
+
* }
|
|
244
|
+
* >;
|
|
245
|
+
* ```
|
|
246
|
+
*/
|
|
247
|
+
export type GqlObject<
|
|
248
|
+
T,
|
|
249
|
+
Meta extends {
|
|
250
|
+
directives?: ReadonlyArray<
|
|
251
|
+
GqlDirective<
|
|
252
|
+
string,
|
|
253
|
+
Record<string, unknown>,
|
|
254
|
+
DirectiveLocation | DirectiveLocation[]
|
|
255
|
+
>
|
|
256
|
+
>;
|
|
257
|
+
implements?: ReadonlyArray<GqlInterfaceMarker>;
|
|
258
|
+
} = { directives: [] },
|
|
259
|
+
> = T & {
|
|
260
|
+
readonly " $gqlkitTypeMeta"?: GqlTypeMetaShape<Meta>;
|
|
261
|
+
readonly " $gqlkitOriginalType"?: T;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Scalar metadata structure embedded in intersection types.
|
|
266
|
+
* Used by CLI to detect and identify scalar types through type analysis.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
* ```typescript
|
|
270
|
+
* // A type with scalar metadata
|
|
271
|
+
* type MyScalar = Base & { " $gqlkitScalar"?: ScalarMetadataShape };
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
export interface ScalarMetadataShape {
|
|
275
|
+
readonly name: string;
|
|
276
|
+
readonly only?: "input" | "output";
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Utility type for defining custom scalar types with metadata.
|
|
281
|
+
* The metadata is embedded as an optional property to maintain compatibility
|
|
282
|
+
* with the underlying base type.
|
|
283
|
+
*
|
|
284
|
+
* @typeParam Name - The GraphQL scalar name
|
|
285
|
+
* @typeParam Base - The underlying TypeScript type
|
|
286
|
+
* @typeParam Only - Usage constraint: "input" for input-only, "output" for output-only, undefined for both
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* ```typescript
|
|
290
|
+
* // Basic custom scalar
|
|
291
|
+
* type DateTime = GqlScalar<"DateTime", Date>;
|
|
292
|
+
*
|
|
293
|
+
* // Input-only scalar
|
|
294
|
+
* type DateTimeInput = GqlScalar<"DateTime", Date, "input">;
|
|
295
|
+
*
|
|
296
|
+
* // Output-only scalar (can accept multiple base types)
|
|
297
|
+
* type DateTimeOutput = GqlScalar<"DateTime", Date | string, "output">;
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
export type GqlScalar<
|
|
301
|
+
Name extends string,
|
|
302
|
+
Base,
|
|
303
|
+
Only extends "input" | "output" | undefined = undefined,
|
|
304
|
+
> = Base & {
|
|
305
|
+
" $gqlkitScalar"?: {
|
|
306
|
+
name: Name;
|
|
307
|
+
only: Only;
|
|
308
|
+
};
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* GraphQL Int scalar type.
|
|
313
|
+
* Use this to explicitly mark a field as an integer.
|
|
314
|
+
* Includes metadata for CLI detection.
|
|
315
|
+
*/
|
|
316
|
+
export type Int = GqlScalar<"Int", number>;
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* GraphQL Float scalar type.
|
|
320
|
+
* Use this to explicitly mark a field as a floating-point number.
|
|
321
|
+
* Note: Plain `number` type will also map to Float by default.
|
|
322
|
+
* Includes metadata for CLI detection.
|
|
323
|
+
*/
|
|
324
|
+
export type Float = GqlScalar<"Float", number>;
|
|
325
|
+
|
|
326
|
+
/**
|
|
327
|
+
* GraphQL ID scalar type (string-based).
|
|
328
|
+
* Use this when the ID is represented as a string in your system.
|
|
329
|
+
* Includes metadata for CLI detection.
|
|
330
|
+
*/
|
|
331
|
+
export type IDString = GqlScalar<"ID", string>;
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* GraphQL ID scalar type (number-based).
|
|
335
|
+
* Use this when the ID is represented as a number in your system.
|
|
336
|
+
* Includes metadata for CLI detection.
|
|
337
|
+
*/
|
|
338
|
+
export type IDNumber = GqlScalar<"ID", number>;
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Type alias representing no arguments for a resolver.
|
|
342
|
+
* Use this when defining resolvers that don't accept any arguments.
|
|
343
|
+
*/
|
|
344
|
+
export type NoArgs = Record<string, never>;
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* Type for Query resolver functions.
|
|
348
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
349
|
+
* @typeParam TResult - The return type of the resolver
|
|
350
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
351
|
+
*/
|
|
352
|
+
export type QueryResolverFn<TArgs, TResult, TContext = unknown> = (
|
|
353
|
+
root: undefined,
|
|
354
|
+
args: TArgs,
|
|
355
|
+
context: TContext,
|
|
356
|
+
info: GraphQLResolveInfo,
|
|
357
|
+
) => TResult | Promise<TResult>;
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Type for Mutation resolver functions.
|
|
361
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
362
|
+
* @typeParam TResult - The return type of the resolver
|
|
363
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
364
|
+
*/
|
|
365
|
+
export type MutationResolverFn<TArgs, TResult, TContext = unknown> = (
|
|
366
|
+
root: undefined,
|
|
367
|
+
args: TArgs,
|
|
368
|
+
context: TContext,
|
|
369
|
+
info: GraphQLResolveInfo,
|
|
370
|
+
) => TResult | Promise<TResult>;
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Type for Field resolver functions.
|
|
374
|
+
* @typeParam TParent - The parent type this field belongs to
|
|
375
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
376
|
+
* @typeParam TResult - The return type of the resolver
|
|
377
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
378
|
+
*/
|
|
379
|
+
export type FieldResolverFn<TParent, TArgs, TResult, TContext = unknown> = (
|
|
380
|
+
parent: TParent,
|
|
381
|
+
args: TArgs,
|
|
382
|
+
context: TContext,
|
|
383
|
+
info: GraphQLResolveInfo,
|
|
384
|
+
) => TResult | Promise<TResult>;
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* The kind of resolver.
|
|
388
|
+
*/
|
|
389
|
+
export type ResolverKind = "query" | "mutation" | "field";
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* The kind of abstract type resolver.
|
|
393
|
+
*/
|
|
394
|
+
export type AbstractResolverKind = "resolveType" | "isTypeOf";
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Type for resolveType resolver functions.
|
|
398
|
+
* Used to resolve the concrete type of a union or interface type at runtime.
|
|
399
|
+
* @typeParam TAbstract - The abstract type (union or interface) to resolve
|
|
400
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
401
|
+
*/
|
|
402
|
+
export type ResolveTypeResolverFn<TAbstract, TContext = unknown> = (
|
|
403
|
+
value: TAbstract,
|
|
404
|
+
context: TContext,
|
|
405
|
+
info: GraphQLResolveInfo,
|
|
406
|
+
) => string | Promise<string>;
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* Type for isTypeOf resolver functions.
|
|
410
|
+
* Used to check if a value belongs to a specific object type.
|
|
411
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
412
|
+
*/
|
|
413
|
+
export type IsTypeOfResolverFn<TContext = unknown> = (
|
|
414
|
+
value: unknown,
|
|
415
|
+
context: TContext,
|
|
416
|
+
info: GraphQLResolveInfo,
|
|
417
|
+
) => boolean | Promise<boolean>;
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Abstract type resolver metadata structure embedded in intersection types.
|
|
421
|
+
* Used by CLI to detect and identify abstract type resolvers through type analysis.
|
|
422
|
+
*/
|
|
423
|
+
export interface AbstractResolverMetadataShape {
|
|
424
|
+
readonly kind: AbstractResolverKind;
|
|
425
|
+
readonly targetType: unknown;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* resolveType resolver type with metadata.
|
|
430
|
+
* The metadata is embedded as an optional property with space-prefixed key
|
|
431
|
+
* to avoid collision with user-defined properties.
|
|
432
|
+
* @typeParam TAbstract - The abstract type (union or interface) to resolve
|
|
433
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
434
|
+
*/
|
|
435
|
+
export type ResolveTypeResolver<
|
|
436
|
+
TAbstract,
|
|
437
|
+
TContext = unknown,
|
|
438
|
+
> = ResolveTypeResolverFn<TAbstract, TContext> & {
|
|
439
|
+
" $gqlkitAbstractResolver"?: {
|
|
440
|
+
kind: "resolveType";
|
|
441
|
+
targetType: TAbstract;
|
|
442
|
+
};
|
|
443
|
+
};
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* isTypeOf resolver type with metadata.
|
|
447
|
+
* The metadata is embedded as an optional property with space-prefixed key
|
|
448
|
+
* to avoid collision with user-defined properties.
|
|
449
|
+
* @typeParam TObject - The object type to check
|
|
450
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
451
|
+
*/
|
|
452
|
+
export type IsTypeOfResolver<
|
|
453
|
+
TObject,
|
|
454
|
+
TContext = unknown,
|
|
455
|
+
> = IsTypeOfResolverFn<TContext> & {
|
|
456
|
+
" $gqlkitAbstractResolver"?: {
|
|
457
|
+
kind: "isTypeOf";
|
|
458
|
+
targetType: TObject;
|
|
459
|
+
};
|
|
460
|
+
};
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Resolver metadata structure embedded in intersection types.
|
|
464
|
+
* Used by CLI to detect and identify resolver types through type analysis.
|
|
465
|
+
*/
|
|
466
|
+
export interface ResolverMetadataShape {
|
|
467
|
+
readonly kind: ResolverKind;
|
|
468
|
+
readonly args: unknown;
|
|
469
|
+
readonly result: unknown;
|
|
470
|
+
readonly parent?: unknown;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Query resolver type with metadata.
|
|
475
|
+
* The metadata is embedded as an optional property with space-prefixed key
|
|
476
|
+
* to avoid collision with user-defined properties.
|
|
477
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
478
|
+
* @typeParam TResult - The return type of the resolver
|
|
479
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
480
|
+
* @typeParam TDirectives - Array of directives to attach to this field (defaults to [])
|
|
481
|
+
*/
|
|
482
|
+
export type QueryResolver<
|
|
483
|
+
TArgs,
|
|
484
|
+
TResult,
|
|
485
|
+
TContext = unknown,
|
|
486
|
+
TDirectives extends ReadonlyArray<
|
|
487
|
+
GqlDirective<
|
|
488
|
+
string,
|
|
489
|
+
Record<string, unknown>,
|
|
490
|
+
DirectiveLocation | DirectiveLocation[]
|
|
491
|
+
>
|
|
492
|
+
> = [],
|
|
493
|
+
> = QueryResolverFn<TArgs, TResult, TContext> & {
|
|
494
|
+
" $gqlkitResolver"?: {
|
|
495
|
+
kind: "query";
|
|
496
|
+
args: TArgs;
|
|
497
|
+
result: TResult;
|
|
498
|
+
directives: TDirectives;
|
|
499
|
+
};
|
|
500
|
+
};
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Mutation resolver type with metadata.
|
|
504
|
+
* The metadata is embedded as an optional property with space-prefixed key
|
|
505
|
+
* to avoid collision with user-defined properties.
|
|
506
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
507
|
+
* @typeParam TResult - The return type of the resolver
|
|
508
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
509
|
+
* @typeParam TDirectives - Array of directives to attach to this field (defaults to [])
|
|
510
|
+
*/
|
|
511
|
+
export type MutationResolver<
|
|
512
|
+
TArgs,
|
|
513
|
+
TResult,
|
|
514
|
+
TContext = unknown,
|
|
515
|
+
TDirectives extends ReadonlyArray<
|
|
516
|
+
GqlDirective<
|
|
517
|
+
string,
|
|
518
|
+
Record<string, unknown>,
|
|
519
|
+
DirectiveLocation | DirectiveLocation[]
|
|
520
|
+
>
|
|
521
|
+
> = [],
|
|
522
|
+
> = MutationResolverFn<TArgs, TResult, TContext> & {
|
|
523
|
+
" $gqlkitResolver"?: {
|
|
524
|
+
kind: "mutation";
|
|
525
|
+
args: TArgs;
|
|
526
|
+
result: TResult;
|
|
527
|
+
directives: TDirectives;
|
|
528
|
+
};
|
|
529
|
+
};
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Field resolver type with metadata.
|
|
533
|
+
* The metadata is embedded as an optional property with space-prefixed key
|
|
534
|
+
* to avoid collision with user-defined properties.
|
|
535
|
+
* @typeParam TParent - The parent type this field belongs to
|
|
536
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
537
|
+
* @typeParam TResult - The return type of the resolver
|
|
538
|
+
* @typeParam TContext - The context type (defaults to unknown)
|
|
539
|
+
* @typeParam TDirectives - Array of directives to attach to this field (defaults to [])
|
|
540
|
+
*/
|
|
541
|
+
export type FieldResolver<
|
|
542
|
+
TParent,
|
|
543
|
+
TArgs,
|
|
544
|
+
TResult,
|
|
545
|
+
TContext = unknown,
|
|
546
|
+
TDirectives extends ReadonlyArray<
|
|
547
|
+
GqlDirective<
|
|
548
|
+
string,
|
|
549
|
+
Record<string, unknown>,
|
|
550
|
+
DirectiveLocation | DirectiveLocation[]
|
|
551
|
+
>
|
|
552
|
+
> = [],
|
|
553
|
+
> = FieldResolverFn<TParent, TArgs, TResult, TContext> & {
|
|
554
|
+
" $gqlkitResolver"?: {
|
|
555
|
+
kind: "field";
|
|
556
|
+
parent: TParent;
|
|
557
|
+
args: TArgs;
|
|
558
|
+
result: TResult;
|
|
559
|
+
directives: TDirectives;
|
|
560
|
+
};
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* The API set returned by createGqlkitApis.
|
|
565
|
+
* Contains typed define functions for Query, Mutation, and Field resolvers.
|
|
566
|
+
* @typeParam TContext - The context type for all resolvers in this API set
|
|
567
|
+
*/
|
|
568
|
+
export interface GqlkitApis<TContext> {
|
|
569
|
+
/**
|
|
570
|
+
* Defines a Query field resolver with the specified Context type.
|
|
571
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
572
|
+
* @typeParam TResult - The return type of the resolver
|
|
573
|
+
* @typeParam TDirectives - Array of directives to attach to this field (defaults to [])
|
|
574
|
+
* @param resolver - The resolver function
|
|
575
|
+
* @returns The resolver with metadata for CLI detection
|
|
576
|
+
*
|
|
577
|
+
* @example
|
|
578
|
+
* ```typescript
|
|
579
|
+
* // Without directives
|
|
580
|
+
* export const users = defineQuery<NoArgs, User[]>(() => []);
|
|
581
|
+
*
|
|
582
|
+
* // With directives
|
|
583
|
+
* export const me = defineQuery<NoArgs, User, [AuthDirective<{ role: ["USER"] }>]>(
|
|
584
|
+
* (root, args, ctx) => ctx.currentUser
|
|
585
|
+
* );
|
|
586
|
+
* ```
|
|
587
|
+
*/
|
|
588
|
+
defineQuery: <
|
|
589
|
+
TArgs,
|
|
590
|
+
TResult,
|
|
591
|
+
TDirectives extends ReadonlyArray<
|
|
592
|
+
GqlDirective<
|
|
593
|
+
string,
|
|
594
|
+
Record<string, unknown>,
|
|
595
|
+
DirectiveLocation | DirectiveLocation[]
|
|
596
|
+
>
|
|
597
|
+
> = [],
|
|
598
|
+
>(
|
|
599
|
+
resolver: QueryResolverFn<TArgs, TResult, TContext>,
|
|
600
|
+
) => QueryResolver<TArgs, TResult, TContext, TDirectives>;
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Defines a Mutation field resolver with the specified Context type.
|
|
604
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
605
|
+
* @typeParam TResult - The return type of the resolver
|
|
606
|
+
* @typeParam TDirectives - Array of directives to attach to this field (defaults to [])
|
|
607
|
+
* @param resolver - The resolver function
|
|
608
|
+
* @returns The resolver with metadata for CLI detection
|
|
609
|
+
*
|
|
610
|
+
* @example
|
|
611
|
+
* ```typescript
|
|
612
|
+
* // Without directives
|
|
613
|
+
* export const createUser = defineMutation<CreateUserInput, User>((root, args) => ({ ... }));
|
|
614
|
+
*
|
|
615
|
+
* // With directives
|
|
616
|
+
* export const deleteUser = defineMutation<{ id: string }, boolean, [AuthDirective<{ role: ["ADMIN"] }>]>(
|
|
617
|
+
* (root, args, ctx) => true
|
|
618
|
+
* );
|
|
619
|
+
* ```
|
|
620
|
+
*/
|
|
621
|
+
defineMutation: <
|
|
622
|
+
TArgs,
|
|
623
|
+
TResult,
|
|
624
|
+
TDirectives extends ReadonlyArray<
|
|
625
|
+
GqlDirective<
|
|
626
|
+
string,
|
|
627
|
+
Record<string, unknown>,
|
|
628
|
+
DirectiveLocation | DirectiveLocation[]
|
|
629
|
+
>
|
|
630
|
+
> = [],
|
|
631
|
+
>(
|
|
632
|
+
resolver: MutationResolverFn<TArgs, TResult, TContext>,
|
|
633
|
+
) => MutationResolver<TArgs, TResult, TContext, TDirectives>;
|
|
634
|
+
|
|
635
|
+
/**
|
|
636
|
+
* Defines an object type field resolver with the specified Context type.
|
|
637
|
+
* @typeParam TParent - The parent type this field belongs to
|
|
638
|
+
* @typeParam TArgs - The type of arguments the resolver accepts
|
|
639
|
+
* @typeParam TResult - The return type of the resolver
|
|
640
|
+
* @typeParam TDirectives - Array of directives to attach to this field (defaults to [])
|
|
641
|
+
* @param resolver - The resolver function
|
|
642
|
+
* @returns The resolver with metadata for CLI detection
|
|
643
|
+
*
|
|
644
|
+
* @example
|
|
645
|
+
* ```typescript
|
|
646
|
+
* // Without directives
|
|
647
|
+
* export const userPosts = defineField<User, NoArgs, Post[]>((parent) => []);
|
|
648
|
+
*
|
|
649
|
+
* // With directives
|
|
650
|
+
* export const userEmail = defineField<User, NoArgs, string, [AuthDirective<{ role: ["ADMIN"] }>]>(
|
|
651
|
+
* (parent) => parent.email
|
|
652
|
+
* );
|
|
653
|
+
* ```
|
|
654
|
+
*/
|
|
655
|
+
defineField: <
|
|
656
|
+
TParent,
|
|
657
|
+
TArgs,
|
|
658
|
+
TResult,
|
|
659
|
+
TDirectives extends ReadonlyArray<
|
|
660
|
+
GqlDirective<
|
|
661
|
+
string,
|
|
662
|
+
Record<string, unknown>,
|
|
663
|
+
DirectiveLocation | DirectiveLocation[]
|
|
664
|
+
>
|
|
665
|
+
> = [],
|
|
666
|
+
>(
|
|
667
|
+
resolver: FieldResolverFn<TParent, TArgs, TResult, TContext>,
|
|
668
|
+
) => FieldResolver<TParent, TArgs, TResult, TContext, TDirectives>;
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Defines a resolveType resolver for union or interface types.
|
|
672
|
+
* Used to determine the concrete type of an abstract type at runtime.
|
|
673
|
+
* @typeParam TAbstract - The abstract type (union or interface) to resolve
|
|
674
|
+
* @param resolver - The resolver function that returns the concrete type name
|
|
675
|
+
* @returns The resolver with metadata for CLI detection
|
|
676
|
+
*
|
|
677
|
+
* @example
|
|
678
|
+
* ```typescript
|
|
679
|
+
* type Animal = Dog | Cat;
|
|
680
|
+
*
|
|
681
|
+
* export const animalResolveType = defineResolveType<Animal>((value) => {
|
|
682
|
+
* return value.kind === "dog" ? "Dog" : "Cat";
|
|
683
|
+
* });
|
|
684
|
+
* ```
|
|
685
|
+
*/
|
|
686
|
+
defineResolveType: <TAbstract>(
|
|
687
|
+
resolver: ResolveTypeResolverFn<TAbstract, TContext>,
|
|
688
|
+
) => ResolveTypeResolver<TAbstract, TContext>;
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Defines an isTypeOf resolver for object types.
|
|
692
|
+
* Used to check if a value belongs to a specific object type.
|
|
693
|
+
* @typeParam TObject - The object type to check
|
|
694
|
+
* @param resolver - The resolver function that returns true if the value is of this type
|
|
695
|
+
* @returns The resolver with metadata for CLI detection
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
* ```typescript
|
|
699
|
+
* export const dogIsTypeOf = defineIsTypeOf<Dog>((value) => {
|
|
700
|
+
* return typeof value === "object" && value !== null && "kind" in value && value.kind === "dog";
|
|
701
|
+
* });
|
|
702
|
+
* ```
|
|
703
|
+
*/
|
|
704
|
+
defineIsTypeOf: <TObject>(
|
|
705
|
+
resolver: IsTypeOfResolverFn<TContext>,
|
|
706
|
+
) => IsTypeOfResolver<TObject, TContext>;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Creates a set of typed define functions for GraphQL resolvers.
|
|
711
|
+
* Use this factory to create API sets with custom Context types.
|
|
712
|
+
*
|
|
713
|
+
* @typeParam TContext - The context type for all resolvers (defaults to unknown)
|
|
714
|
+
* @returns An object containing defineQuery, defineMutation, and defineField functions
|
|
715
|
+
*
|
|
716
|
+
* @example
|
|
717
|
+
* ```typescript
|
|
718
|
+
* type MyContext = { userId: string; db: Database };
|
|
719
|
+
*
|
|
720
|
+
* const { defineQuery, defineMutation, defineField } = createGqlkitApis<MyContext>();
|
|
721
|
+
*
|
|
722
|
+
* export const me = defineQuery<NoArgs, User>(
|
|
723
|
+
* (root, args, ctx, info) => ctx.db.findUser(ctx.userId)
|
|
724
|
+
* );
|
|
725
|
+
* ```
|
|
726
|
+
*
|
|
727
|
+
* @example
|
|
728
|
+
* ```typescript
|
|
729
|
+
* // Multiple schemas with different contexts
|
|
730
|
+
* type AdminContext = { adminId: string };
|
|
731
|
+
* type PublicContext = { sessionId: string };
|
|
732
|
+
*
|
|
733
|
+
* const adminApis = createGqlkitApis<AdminContext>();
|
|
734
|
+
* const publicApis = createGqlkitApis<PublicContext>();
|
|
735
|
+
* ```
|
|
736
|
+
*/
|
|
737
|
+
export function createGqlkitApis<TContext = unknown>(): GqlkitApis<TContext> {
|
|
738
|
+
const apis = {
|
|
739
|
+
defineQuery: <TArgs, TResult>(
|
|
740
|
+
resolver: QueryResolverFn<TArgs, TResult, TContext>,
|
|
741
|
+
) => {
|
|
742
|
+
return resolver;
|
|
743
|
+
},
|
|
744
|
+
defineMutation: <TArgs, TResult>(
|
|
745
|
+
resolver: MutationResolverFn<TArgs, TResult, TContext>,
|
|
746
|
+
) => {
|
|
747
|
+
return resolver;
|
|
748
|
+
},
|
|
749
|
+
defineField: <TParent, TArgs, TResult>(
|
|
750
|
+
resolver: FieldResolverFn<TParent, TArgs, TResult, TContext>,
|
|
751
|
+
) => {
|
|
752
|
+
return resolver;
|
|
753
|
+
},
|
|
754
|
+
defineResolveType: <TAbstract>(
|
|
755
|
+
resolver: ResolveTypeResolverFn<TAbstract, TContext>,
|
|
756
|
+
) => {
|
|
757
|
+
return resolver;
|
|
758
|
+
},
|
|
759
|
+
defineIsTypeOf: (resolver: IsTypeOfResolverFn<TContext>) => {
|
|
760
|
+
return resolver;
|
|
761
|
+
},
|
|
762
|
+
};
|
|
763
|
+
return apis as unknown as GqlkitApis<TContext>;
|
|
764
|
+
}
|