Skip to content

Commit d75f60f

Browse files
fix: add typed-document-node plugin to SDK generation
documentMode: 'string' causes visitor-plugin-common to emit `new TypedDocumentString(...)` calls. The class definition is provided by @graphql-codegen/typed-document-node plugin via its prepend mechanism. Without this plugin in the SDK pipeline, the class was undefined at runtime. Now the official plugin handles it — no custom class injection needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5da3ba2 commit d75f60f

2 files changed

Lines changed: 59 additions & 11 deletions

File tree

playgrounds/nitro/graphql/default/sdk.ts

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,65 @@
55
/* prettier-ignore */
66
import type * as Types from '#graphql/client';
77

8-
import type { DocumentNode, ExecutionResult } from 'graphql';
9-
import gql from 'graphql-tag';
8+
import type { DocumentTypeDecoration } from '@graphql-typed-document-node/core';
9+
import type { ExecutionResult } from 'graphql';
10+
export class TypedDocumentString<TResult, TVariables>
11+
extends String
12+
implements DocumentTypeDecoration<TResult, TVariables>
13+
{
14+
__apiType?: NonNullable<DocumentTypeDecoration<TResult, TVariables>['__apiType']>;
15+
private value: string;
16+
public __meta__?: Record<string, any> | undefined;
1017

11-
export const HelloDocument = /*#__PURE__*/ gql`
18+
constructor(value: string, __meta__?: Record<string, any> | undefined) {
19+
super(value);
20+
this.value = value;
21+
this.__meta__ = __meta__;
22+
}
23+
24+
override toString(): string & DocumentTypeDecoration<TResult, TVariables> {
25+
return this.value;
26+
}
27+
}
28+
29+
export const HelloDocument = /*#__PURE__*/ new TypedDocumentString(`
30+
query Hello {
31+
helloCI
32+
}
33+
`) as unknown as TypedDocumentString<Types.HelloQuery, Types.HelloQueryVariables>;
34+
export const GetUsersDocument = /*#__PURE__*/ new TypedDocumentString(`
35+
query GetUsers {
36+
users {
37+
id
38+
name
39+
}
40+
}
41+
`) as unknown as TypedDocumentString<Types.GetUsersQuery, Types.GetUsersQueryVariables>;
42+
export const GetGreetingDocument = /*#__PURE__*/ new TypedDocumentString(`
43+
query GetGreeting {
44+
greeting(name: "World")
45+
}
46+
`) as unknown as TypedDocumentString<Types.GetGreetingQuery, Types.GetGreetingQueryVariables>;
47+
48+
export const HelloDocument = /*#__PURE__*/ new TypedDocumentString(`
1249
query Hello {
1350
helloCI
1451
}
15-
`;
16-
export const GetUsersDocument = /*#__PURE__*/ gql`
52+
`);
53+
export const GetUsersDocument = /*#__PURE__*/ new TypedDocumentString(`
1754
query GetUsers {
1855
users {
1956
id
2057
name
2158
}
2259
}
23-
`;
24-
export const GetGreetingDocument = /*#__PURE__*/ gql`
60+
`);
61+
export const GetGreetingDocument = /*#__PURE__*/ new TypedDocumentString(`
2562
query GetGreeting {
2663
greeting(name: "World")
2764
}
28-
`;
29-
export type Requester<C = {}, E = unknown> = <R, V>(doc: DocumentNode, vars?: V, options?: C) => Promise<ExecutionResult<R, E>> | AsyncIterable<ExecutionResult<R, E>>
65+
`);
66+
export type Requester<C = {}, E = unknown> = <R, V>(doc: string, vars?: V, options?: C) => Promise<ExecutionResult<R, E>> | AsyncIterable<ExecutionResult<R, E>>
3067
export function getSdk<C, E>(requester: Requester<C, E>) {
3168
return {
3269
Hello(variables?: Types.HelloQueryVariables, options?: C): Promise<ExecutionResult<Types.HelloQuery, E>> {

src/core/codegen/client.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,14 +143,25 @@ export async function generateClientTypesCore(
143143
// SDK generation via import-types-preset
144144
const typesPath = virtualTypesPath || (serviceName ? `#graphql/client/${serviceName}` : '#graphql/client')
145145

146+
// typed-document-node plugin emits TypedDocumentString class definition
147+
// needed when documentMode is 'string' (visitor-plugin-common generates `new TypedDocumentString(...)`)
148+
const sdkPlugins: Array<Record<string, object>> = [
149+
{ typedDocumentNode: {} },
150+
{ typescriptGenericSdk: {} },
151+
]
152+
const sdkPluginMap: Record<string, { plugin: unknown }> = {
153+
typedDocumentNode: { plugin: typedDocumentNodePlugin },
154+
typescriptGenericSdk: { plugin: typescriptGenericSdk },
155+
}
156+
146157
const sdkOutput = await preset.buildGeneratesSection({
147158
baseOutputDir: outputPath || 'client-types.generated.ts',
148159
schema: parsedSchema,
149160
documents: [...documents],
150161
config: resolvedSdkConfig,
151162
presetConfig: { typesPath },
152-
plugins: [{ typescriptGenericSdk: {} }],
153-
pluginMap: { typescriptGenericSdk: { plugin: typescriptGenericSdk } },
163+
plugins: sdkPlugins,
164+
pluginMap: sdkPluginMap,
154165
})
155166

156167
const results = await Promise.all(

0 commit comments

Comments
 (0)