@gqlkit-ts/cli 0.6.0 → 0.7.0
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/dist/auto-type-generator/auto-type-generator.d.ts +7 -0
- package/dist/auto-type-generator/auto-type-generator.d.ts.map +1 -1
- package/dist/auto-type-generator/auto-type-generator.js +375 -55
- package/dist/auto-type-generator/auto-type-generator.js.map +1 -1
- package/dist/auto-type-generator/discriminator-field-validator.d.ts +26 -0
- package/dist/auto-type-generator/discriminator-field-validator.d.ts.map +1 -0
- package/dist/auto-type-generator/discriminator-field-validator.js +242 -0
- package/dist/auto-type-generator/discriminator-field-validator.js.map +1 -0
- package/dist/auto-type-generator/discriminator-naming.d.ts +11 -0
- package/dist/auto-type-generator/discriminator-naming.d.ts.map +1 -0
- package/dist/auto-type-generator/discriminator-naming.js +15 -0
- package/dist/auto-type-generator/discriminator-naming.js.map +1 -0
- package/dist/auto-type-generator/discriminator-resolve-type-generator.d.ts +44 -0
- package/dist/auto-type-generator/discriminator-resolve-type-generator.d.ts.map +1 -0
- package/dist/auto-type-generator/discriminator-resolve-type-generator.js +77 -0
- package/dist/auto-type-generator/discriminator-resolve-type-generator.js.map +1 -0
- package/dist/auto-type-generator/index.d.ts +3 -0
- package/dist/auto-type-generator/index.d.ts.map +1 -1
- package/dist/auto-type-generator/index.js +3 -0
- package/dist/auto-type-generator/index.js.map +1 -1
- package/dist/auto-type-generator/inline-enum-collector.d.ts.map +1 -1
- package/dist/auto-type-generator/inline-enum-collector.js +14 -7
- package/dist/auto-type-generator/inline-enum-collector.js.map +1 -1
- package/dist/auto-type-generator/inline-object-converter.d.ts +12 -0
- package/dist/auto-type-generator/inline-object-converter.d.ts.map +1 -0
- package/dist/auto-type-generator/inline-object-converter.js +72 -0
- package/dist/auto-type-generator/inline-object-converter.js.map +1 -0
- package/dist/auto-type-generator/inline-object-traverser.d.ts +2 -1
- package/dist/auto-type-generator/inline-object-traverser.d.ts.map +1 -1
- package/dist/auto-type-generator/inline-object-traverser.js +22 -4
- package/dist/auto-type-generator/inline-object-traverser.js.map +1 -1
- package/dist/auto-type-generator/inline-union-collector.d.ts.map +1 -1
- package/dist/auto-type-generator/inline-union-collector.js +20 -6
- package/dist/auto-type-generator/inline-union-collector.js.map +1 -1
- package/dist/auto-type-generator/inline-union-types.d.ts +2 -0
- package/dist/auto-type-generator/inline-union-types.d.ts.map +1 -1
- package/dist/auto-type-generator/inline-union-validator.js +3 -3
- package/dist/auto-type-generator/inline-union-validator.js.map +1 -1
- package/dist/auto-type-generator/intersection-flattener.d.ts +44 -0
- package/dist/auto-type-generator/intersection-flattener.d.ts.map +1 -0
- package/dist/auto-type-generator/intersection-flattener.js +398 -0
- package/dist/auto-type-generator/intersection-flattener.js.map +1 -0
- package/dist/auto-type-generator/naming-convention.d.ts +21 -0
- package/dist/auto-type-generator/naming-convention.d.ts.map +1 -1
- package/dist/auto-type-generator/naming-convention.js +145 -1
- package/dist/auto-type-generator/naming-convention.js.map +1 -1
- package/dist/auto-type-generator/typename-extractor.d.ts +2 -0
- package/dist/auto-type-generator/typename-extractor.d.ts.map +1 -1
- package/dist/auto-type-generator/typename-extractor.js +11 -3
- package/dist/auto-type-generator/typename-extractor.js.map +1 -1
- package/dist/auto-type-generator/typename-resolve-type-generator.d.ts +2 -0
- package/dist/auto-type-generator/typename-resolve-type-generator.d.ts.map +1 -1
- package/dist/auto-type-generator/typename-resolve-type-generator.js +12 -84
- package/dist/auto-type-generator/typename-resolve-type-generator.js.map +1 -1
- package/dist/auto-type-generator/typename-types.d.ts +4 -0
- package/dist/auto-type-generator/typename-types.d.ts.map +1 -1
- package/dist/auto-type-generator/typename-types.js +6 -0
- package/dist/auto-type-generator/typename-types.js.map +1 -1
- package/dist/auto-type-generator/typename-validator.d.ts.map +1 -1
- package/dist/auto-type-generator/typename-validator.js +4 -3
- package/dist/auto-type-generator/typename-validator.js.map +1 -1
- package/dist/commands/gen.d.ts.map +1 -1
- package/dist/commands/gen.js +2 -1
- package/dist/commands/gen.js.map +1 -1
- package/dist/config/types.d.ts +7 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config-loader/index.d.ts +1 -1
- package/dist/config-loader/index.d.ts.map +1 -1
- package/dist/config-loader/index.js.map +1 -1
- package/dist/config-loader/loader.d.ts +6 -0
- package/dist/config-loader/loader.d.ts.map +1 -1
- package/dist/config-loader/loader.js +1 -0
- package/dist/config-loader/loader.js.map +1 -1
- package/dist/config-loader/validator.d.ts.map +1 -1
- package/dist/config-loader/validator.js +84 -1
- package/dist/config-loader/validator.js.map +1 -1
- package/dist/gen-orchestrator/orchestrator.d.ts +2 -1
- package/dist/gen-orchestrator/orchestrator.d.ts.map +1 -1
- package/dist/gen-orchestrator/orchestrator.js +15 -2
- package/dist/gen-orchestrator/orchestrator.js.map +1 -1
- package/dist/resolver-extractor/extractor/define-api-extractor.d.ts.map +1 -1
- package/dist/resolver-extractor/extractor/define-api-extractor.js +4 -0
- package/dist/resolver-extractor/extractor/define-api-extractor.js.map +1 -1
- package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts +2 -0
- package/dist/resolver-extractor/validator/abstract-resolver-validator.d.ts.map +1 -1
- package/dist/resolver-extractor/validator/abstract-resolver-validator.js +16 -3
- package/dist/resolver-extractor/validator/abstract-resolver-validator.js.map +1 -1
- package/dist/schema-generator/emitter/code-emitter.d.ts.map +1 -1
- package/dist/schema-generator/emitter/code-emitter.js +13 -1
- package/dist/schema-generator/emitter/code-emitter.js.map +1 -1
- package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.d.ts +18 -0
- package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.d.ts.map +1 -0
- package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.js +89 -0
- package/dist/schema-generator/emitter/discriminator-resolve-type-emitter.js.map +1 -0
- package/dist/schema-generator/generate-schema.d.ts +2 -0
- package/dist/schema-generator/generate-schema.d.ts.map +1 -1
- package/dist/schema-generator/generate-schema.js +69 -10
- package/dist/schema-generator/generate-schema.js.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.d.ts +4 -0
- package/dist/schema-generator/integrator/result-integrator.d.ts.map +1 -1
- package/dist/schema-generator/integrator/result-integrator.js +18 -2
- package/dist/schema-generator/integrator/result-integrator.js.map +1 -1
- package/dist/schema-generator/resolver-collector/resolver-collector.d.ts +2 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.d.ts.map +1 -1
- package/dist/schema-generator/resolver-collector/resolver-collector.js +4 -0
- package/dist/schema-generator/resolver-collector/resolver-collector.js.map +1 -1
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +14 -1
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/enum-prefix-detector.d.ts.map +1 -1
- package/dist/shared/enum-prefix-detector.js +78 -8
- package/dist/shared/enum-prefix-detector.js.map +1 -1
- package/dist/shared/inline-object-utils.js +1 -1
- package/dist/shared/inline-object-utils.js.map +1 -1
- package/dist/shared/type-converter.d.ts.map +1 -1
- package/dist/shared/type-converter.js +55 -0
- package/dist/shared/type-converter.js.map +1 -1
- package/dist/type-extractor/converter/graphql-converter.d.ts.map +1 -1
- package/dist/type-extractor/converter/graphql-converter.js +11 -1
- package/dist/type-extractor/converter/graphql-converter.js.map +1 -1
- package/dist/type-extractor/extractor/field-type-resolver.d.ts +18 -0
- package/dist/type-extractor/extractor/field-type-resolver.d.ts.map +1 -1
- package/dist/type-extractor/extractor/field-type-resolver.js +198 -15
- package/dist/type-extractor/extractor/field-type-resolver.js.map +1 -1
- package/dist/type-extractor/extractor/type-extractor.d.ts +1 -0
- package/dist/type-extractor/extractor/type-extractor.d.ts.map +1 -1
- package/dist/type-extractor/extractor/type-extractor.js +100 -9
- package/dist/type-extractor/extractor/type-extractor.js.map +1 -1
- package/dist/type-extractor/types/diagnostics.d.ts +1 -1
- package/dist/type-extractor/types/diagnostics.d.ts.map +1 -1
- package/dist/type-extractor/types/index.d.ts +1 -1
- package/dist/type-extractor/types/index.d.ts.map +1 -1
- package/dist/type-extractor/types/index.js +1 -1
- package/dist/type-extractor/types/index.js.map +1 -1
- package/dist/type-extractor/types/ts-type-reference-factory.d.ts +7 -1
- package/dist/type-extractor/types/ts-type-reference-factory.d.ts.map +1 -1
- package/dist/type-extractor/types/ts-type-reference-factory.js +18 -3
- package/dist/type-extractor/types/ts-type-reference-factory.js.map +1 -1
- package/dist/type-extractor/types/typescript.d.ts +3 -1
- package/dist/type-extractor/types/typescript.d.ts.map +1 -1
- package/dist/type-extractor/validator/type-validator.d.ts.map +1 -1
- package/dist/type-extractor/validator/type-validator.js +6 -1
- package/dist/type-extractor/validator/type-validator.js.map +1 -1
- package/docs/configuration.md +19 -0
- package/docs/index.md +1 -0
- package/docs/integration/ai-sdk.md +189 -0
- package/docs/schema/unions.md +117 -0
- package/package.json +2 -2
- package/src/auto-type-generator/auto-type-generator.ts +576 -58
- package/src/auto-type-generator/discriminator-field-validator.ts +368 -0
- package/src/auto-type-generator/discriminator-naming.ts +24 -0
- package/src/auto-type-generator/discriminator-resolve-type-generator.ts +136 -0
- package/src/auto-type-generator/index.ts +17 -0
- package/src/auto-type-generator/inline-enum-collector.ts +19 -4
- package/src/auto-type-generator/inline-object-converter.ts +100 -0
- package/src/auto-type-generator/inline-object-traverser.ts +33 -7
- package/src/auto-type-generator/inline-union-collector.ts +26 -4
- package/src/auto-type-generator/inline-union-types.ts +2 -0
- package/src/auto-type-generator/inline-union-validator.ts +3 -3
- package/src/auto-type-generator/intersection-flattener.ts +554 -0
- package/src/auto-type-generator/naming-convention.ts +205 -1
- package/src/auto-type-generator/typename-extractor.ts +17 -3
- package/src/auto-type-generator/typename-resolve-type-generator.ts +19 -108
- package/src/auto-type-generator/typename-types.ts +7 -0
- package/src/auto-type-generator/typename-validator.ts +4 -3
- package/src/commands/gen.ts +9 -2
- package/src/config/types.ts +10 -0
- package/src/config-loader/index.ts +1 -0
- package/src/config-loader/loader.ts +11 -0
- package/src/config-loader/validator.ts +100 -1
- package/src/gen-orchestrator/orchestrator.ts +19 -2
- package/src/resolver-extractor/extractor/define-api-extractor.ts +4 -0
- package/src/resolver-extractor/validator/abstract-resolver-validator.ts +20 -6
- package/src/schema-generator/emitter/code-emitter.ts +26 -1
- package/src/schema-generator/emitter/discriminator-resolve-type-emitter.ts +125 -0
- package/src/schema-generator/generate-schema.ts +100 -13
- package/src/schema-generator/integrator/result-integrator.ts +25 -1
- package/src/schema-generator/resolver-collector/resolver-collector.ts +7 -0
- package/src/shared/constants.ts +15 -1
- package/src/shared/enum-prefix-detector.ts +96 -8
- package/src/shared/inline-object-utils.ts +1 -1
- package/src/shared/type-converter.ts +63 -0
- package/src/type-extractor/converter/graphql-converter.ts +17 -1
- package/src/type-extractor/extractor/field-type-resolver.ts +241 -16
- package/src/type-extractor/extractor/type-extractor.ts +119 -5
- package/src/type-extractor/types/diagnostics.ts +10 -1
- package/src/type-extractor/types/index.ts +2 -1
- package/src/type-extractor/types/ts-type-reference-factory.ts +24 -3
- package/src/type-extractor/types/typescript.ts +6 -2
- package/src/type-extractor/validator/type-validator.ts +6 -1
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Integration with Vercel AI SDK
|
|
3
|
+
description: Stream AI responses as GraphQL subscriptions using the Vercel AI SDK.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vercel AI SDK
|
|
7
|
+
|
|
8
|
+
The [Vercel AI SDK](https://ai-sdk.dev/) provides a unified API for working with large language models. gqlkit integrates with the AI SDK by automatically converting its rich message types — including tool invocations, step boundaries, and custom data parts — into GraphQL unions and subscriptions.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```sh filename="npm"
|
|
13
|
+
npm install ai @ai-sdk/openai
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```sh filename="pnpm"
|
|
17
|
+
pnpm add ai @ai-sdk/openai
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
```sh filename="yarn"
|
|
21
|
+
yarn add ai @ai-sdk/openai
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Defining Tools
|
|
25
|
+
|
|
26
|
+
Define AI tools using the AI SDK's `tool()` helper. The `ToolSet` and `InferUITools` types let you derive strongly-typed UI tool representations:
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// src/agent.ts
|
|
30
|
+
import type { InferUITools, ToolSet, UIMessage } from "ai";
|
|
31
|
+
import { tool } from "ai";
|
|
32
|
+
import { z } from "zod";
|
|
33
|
+
|
|
34
|
+
export const tools = {
|
|
35
|
+
weather: tool({
|
|
36
|
+
description: "Get current weather for a location",
|
|
37
|
+
inputSchema: z.object({
|
|
38
|
+
location: z.string().describe("City name"),
|
|
39
|
+
}),
|
|
40
|
+
execute: async ({ location }) => ({
|
|
41
|
+
location,
|
|
42
|
+
temperature: 72,
|
|
43
|
+
condition: "sunny" as const,
|
|
44
|
+
}),
|
|
45
|
+
}),
|
|
46
|
+
calculate: tool({
|
|
47
|
+
description: "Calculate a math expression",
|
|
48
|
+
inputSchema: z.object({
|
|
49
|
+
expression: z.string().describe("Math expression"),
|
|
50
|
+
}),
|
|
51
|
+
execute: async ({ expression }) => ({
|
|
52
|
+
expression,
|
|
53
|
+
result: 42,
|
|
54
|
+
}),
|
|
55
|
+
}),
|
|
56
|
+
} satisfies ToolSet;
|
|
57
|
+
|
|
58
|
+
export type AppTools = InferUITools<typeof tools>;
|
|
59
|
+
|
|
60
|
+
export type AppMetadata = {
|
|
61
|
+
model: string;
|
|
62
|
+
timestamp: number;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export type AppData = {
|
|
66
|
+
chart: { labels: string[]; values: number[] };
|
|
67
|
+
suggestion: { text: string; confidence: number };
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type AppMessage = UIMessage<AppMetadata, AppData, AppTools>;
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Defining the Message Type
|
|
74
|
+
|
|
75
|
+
Re-export your `AppMessage` as a named type in the gqlkit schema directory. gqlkit discovers the `UIMessage` fields — including the `parts` union — transitively, so you don't need to manually define each part type:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// src/gqlkit/schema/message.ts
|
|
79
|
+
import type { NoArgs } from "@gqlkit-ts/runtime";
|
|
80
|
+
import type { AppMessage } from "../../agent.js";
|
|
81
|
+
import { defineQuery } from "../gqlkit.js";
|
|
82
|
+
|
|
83
|
+
// Re-export AppMessage as Message — gqlkit discovers UIMessage fields transitively.
|
|
84
|
+
export type Message = AppMessage;
|
|
85
|
+
|
|
86
|
+
export const messages = defineQuery<NoArgs, Message[]>(() => mockMessages);
|
|
87
|
+
export const message = defineQuery<{ id: string }, Message | null>(
|
|
88
|
+
(_root, args) => mockMessages.find((m) => m.id === args.id) ?? null,
|
|
89
|
+
);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The `parts` field on `UIMessage` is a discriminated union of text parts, tool invocations, tool results, step boundaries, source parts, file parts, reasoning parts, and your custom data parts. gqlkit automatically generates a corresponding GraphQL union type for this.
|
|
93
|
+
|
|
94
|
+
## Defining Subscriptions
|
|
95
|
+
|
|
96
|
+
The AI SDK provides two streaming patterns that map naturally to GraphQL subscriptions:
|
|
97
|
+
|
|
98
|
+
### Raw Stream (chunk-by-chunk)
|
|
99
|
+
|
|
100
|
+
Use `toUIMessageStream()` to yield each `UIMessageChunk` as it arrives:
|
|
101
|
+
|
|
102
|
+
```typescript
|
|
103
|
+
// src/gqlkit/schema/subscription.ts
|
|
104
|
+
import type { InferUIMessageChunk } from "ai";
|
|
105
|
+
import { streamText } from "ai";
|
|
106
|
+
import type { AppMessage } from "../../agent.js";
|
|
107
|
+
import { tools } from "../../agent.js";
|
|
108
|
+
import { defineSubscription } from "../gqlkit.js";
|
|
109
|
+
|
|
110
|
+
export type ChatStreamChunk = InferUIMessageChunk<AppMessage>;
|
|
111
|
+
|
|
112
|
+
export const chatStream = defineSubscription<
|
|
113
|
+
{ prompt: string },
|
|
114
|
+
ChatStreamChunk
|
|
115
|
+
>(async (_root, args, ctx) => {
|
|
116
|
+
const result = streamText({ model: ctx.model, prompt: args.prompt, tools });
|
|
117
|
+
return result.toUIMessageStream<AppMessage>();
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Assembled Message (progressive updates)
|
|
122
|
+
|
|
123
|
+
Use `readUIMessageStream()` to yield the progressively-built `Message` on each update:
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
import { readUIMessageStream, streamText } from "ai";
|
|
127
|
+
import type { AppMessage } from "../../agent.js";
|
|
128
|
+
import { tools } from "../../agent.js";
|
|
129
|
+
import { defineSubscription } from "../gqlkit.js";
|
|
130
|
+
import type { Message } from "./message.js";
|
|
131
|
+
|
|
132
|
+
export const chat = defineSubscription<{ prompt: string }, Message>(
|
|
133
|
+
async (_root, args, ctx) => {
|
|
134
|
+
const result = streamText({ model: ctx.model, prompt: args.prompt, tools });
|
|
135
|
+
return readUIMessageStream<AppMessage>({
|
|
136
|
+
stream: result.toUIMessageStream(),
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Discriminator Fields Configuration
|
|
143
|
+
|
|
144
|
+
The AI SDK's union types use discriminator fields that gqlkit needs to know about. Configure them in `gqlkit.config.ts`:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
// gqlkit.config.ts
|
|
148
|
+
import type { GqlkitConfig } from "@gqlkit-ts/cli";
|
|
149
|
+
|
|
150
|
+
const config: GqlkitConfig = {
|
|
151
|
+
discriminatorFields: {
|
|
152
|
+
// Message.parts union — discriminated by "type" with "state" as a secondary field
|
|
153
|
+
MessageParts: ["type", "state"],
|
|
154
|
+
// UIMessageChunk variants — discriminated by "type"
|
|
155
|
+
ChatStreamChunk: ["type"],
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
export default config;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
The `discriminatorFields` option tells gqlkit which fields to use when generating the GraphQL union's `__resolveType` implementation.
|
|
163
|
+
|
|
164
|
+
## Context with Language Model
|
|
165
|
+
|
|
166
|
+
Inject the `LanguageModel` via context so resolvers stay testable and model-agnostic. For basic setup, see [Set Up Context and Resolver Factories](../getting-started.md#set-up-context-and-resolver-factories).
|
|
167
|
+
|
|
168
|
+
```typescript
|
|
169
|
+
// src/gqlkit/context.ts
|
|
170
|
+
import type { LanguageModel } from "ai";
|
|
171
|
+
|
|
172
|
+
export type Context = {
|
|
173
|
+
model: LanguageModel;
|
|
174
|
+
};
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Complete Example
|
|
178
|
+
|
|
179
|
+
See the [examples/with-ai-sdk](https://github.com/gqlkit/gqlkit/tree/main/examples/with-ai-sdk) directory for a complete working example with:
|
|
180
|
+
|
|
181
|
+
- Tool definitions with Zod schemas
|
|
182
|
+
- `UIMessage` with custom metadata, data parts, and tool types
|
|
183
|
+
- Both streaming patterns (`chatStream` and `chat` subscriptions)
|
|
184
|
+
- Discriminator fields configuration
|
|
185
|
+
|
|
186
|
+
## Further Reading
|
|
187
|
+
|
|
188
|
+
- [AI SDK Documentation](https://ai-sdk.dev/docs)
|
|
189
|
+
- [AI SDK GitHub](https://github.com/vercel/ai)
|
package/docs/schema/unions.md
CHANGED
|
@@ -279,6 +279,123 @@ export type SearchResult = User | Post;
|
|
|
279
279
|
// resolveType is automatically generated - no manual definition needed
|
|
280
280
|
```
|
|
281
281
|
|
|
282
|
+
### Custom Discriminator Fields
|
|
283
|
+
|
|
284
|
+
When union member types use a field other than `__typename` or `$typeName` for discrimination (e.g., external library types like AI SDK's `UIMessagePart`), you can configure custom discriminator fields via `gqlkit.config.ts`. gqlkit will automatically generate `__resolveType` based on the specified fields.
|
|
285
|
+
|
|
286
|
+
```ts
|
|
287
|
+
// gqlkit.config.ts
|
|
288
|
+
import { defineConfig } from "@gqlkit-ts/cli";
|
|
289
|
+
|
|
290
|
+
export default defineConfig({
|
|
291
|
+
discriminatorFields: {
|
|
292
|
+
ContentPart: "type",
|
|
293
|
+
},
|
|
294
|
+
});
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
// src/gqlkit/schema/types.ts
|
|
299
|
+
export interface TextPart {
|
|
300
|
+
type: "text";
|
|
301
|
+
text: string;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export interface ImagePart {
|
|
305
|
+
type: "image";
|
|
306
|
+
url: string;
|
|
307
|
+
alt: string;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export type ContentPart = TextPart | ImagePart;
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
Generates a `switch`-based `__resolveType`:
|
|
314
|
+
|
|
315
|
+
```typescript
|
|
316
|
+
ContentPart: {
|
|
317
|
+
__resolveType: (obj) => {
|
|
318
|
+
switch (obj.type) {
|
|
319
|
+
case "text": return "TextPart";
|
|
320
|
+
case "image": return "ImagePart";
|
|
321
|
+
default: return undefined;
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Unlike `__typename` or `$typeName`, custom discriminator fields remain as regular GraphQL fields in the generated schema:
|
|
328
|
+
|
|
329
|
+
```graphql
|
|
330
|
+
union ContentPart = ImagePart | TextPart
|
|
331
|
+
|
|
332
|
+
type TextPart {
|
|
333
|
+
type: String!
|
|
334
|
+
text: String!
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
type ImagePart {
|
|
338
|
+
type: String!
|
|
339
|
+
url: String!
|
|
340
|
+
alt: String!
|
|
341
|
+
}
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### Multiple Discriminator Fields
|
|
345
|
+
|
|
346
|
+
When a single field is not enough to uniquely identify each member, you can specify multiple discriminator fields as an array. The first field must exist on all members with a string literal type. Secondary fields do not need to exist on every member.
|
|
347
|
+
|
|
348
|
+
```ts
|
|
349
|
+
// gqlkit.config.ts
|
|
350
|
+
import { defineConfig } from "@gqlkit-ts/cli";
|
|
351
|
+
|
|
352
|
+
export default defineConfig({
|
|
353
|
+
discriminatorFields: {
|
|
354
|
+
Content: ["type", "mediaType"],
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
```typescript
|
|
360
|
+
export type Content =
|
|
361
|
+
| { type: "text"; mediaType: "plain"; body: string }
|
|
362
|
+
| { type: "text"; mediaType: "html"; html: string }
|
|
363
|
+
| { type: "image"; url: string; alt: string };
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Generates nested `switch` statements and type names derived from the discriminator values:
|
|
367
|
+
|
|
368
|
+
```graphql
|
|
369
|
+
union Content = ContentImage | ContentTextHtml | ContentTextPlain
|
|
370
|
+
|
|
371
|
+
type ContentTextPlain {
|
|
372
|
+
type: String!
|
|
373
|
+
mediaType: String!
|
|
374
|
+
body: String!
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
type ContentTextHtml {
|
|
378
|
+
type: String!
|
|
379
|
+
mediaType: String!
|
|
380
|
+
html: String!
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
type ContentImage {
|
|
384
|
+
type: String!
|
|
385
|
+
url: String!
|
|
386
|
+
alt: String!
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Validation Rules
|
|
391
|
+
|
|
392
|
+
- The **first** discriminator field must exist on **all** union members and have a string literal type
|
|
393
|
+
- Secondary fields do not need to exist on every member, but the combination of values must be unique across all members
|
|
394
|
+
- If a `defineResolveType` is manually defined for the same union, the manual definition takes priority
|
|
395
|
+
- If `discriminatorFields` is configured for a union that also has `$typeName` or `__typename`, the `discriminatorFields` configuration takes priority
|
|
396
|
+
|
|
397
|
+
See [Configuration](../configuration.md#custom-discriminator-fields) for the full config reference.
|
|
398
|
+
|
|
282
399
|
### Manual Resolution
|
|
283
400
|
|
|
284
401
|
For types without `__typename` or `$typeName`, use `defineResolveType`:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gqlkit-ts/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Just types and functions — write TypeScript, generate GraphQL.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@types/shell-quote": "1.7.5",
|
|
62
|
-
"memfs": "4.56.
|
|
62
|
+
"memfs": "4.56.11",
|
|
63
63
|
"@gqlkit-ts/docs": "0.0.1",
|
|
64
64
|
"@gqlkit-ts/runtime": "0.3.0"
|
|
65
65
|
},
|