From 45dec125a32bfc5e421de1c65a2a8b41e56959e4 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 26 Sep 2026 13:28:57 +0000 Subject: [PATCH 1/3] [graphql-modules-preset] fix: skip sources without a location or document under strict mode (#4683) Fixes the 7 errors `presets/graphql-modules` hits once the root tsconfig enables `strict: true`: - builder.ts: `node.interfaces?.length > 0` compared a possibly-undefined value; default it to 0 (TS18048). - index.ts: `Source.document` is optional, so skip sources without one before `concatAST`, matching core (TS2345). - index.ts: `getConfigValue` infers `T` from the nullable input, so it returned `boolean | undefined`; use `?? true` for `useGraphQLModules` (TS2322). - index.ts: `.filter(Boolean)` does not narrow `rootTypes`; use a `string` type guard (TS2322). - utils.ts: `Source.location` is optional and `path.normalize(undefined)` throws, so skip sources without one in `groupSourcesByModule` (TS2345). Generated output from the CLI is unchanged. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XSMiQQc6YQZUo1EajQncWL eddeee888:oss:issue-fix --- .changeset/brave-modules-skip.md | 5 +++++ packages/presets/graphql-modules/src/builder.ts | 4 ++-- packages/presets/graphql-modules/src/index.ts | 8 +++++--- packages/presets/graphql-modules/src/utils.ts | 4 ++++ 4 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .changeset/brave-modules-skip.md diff --git a/.changeset/brave-modules-skip.md b/.changeset/brave-modules-skip.md new file mode 100644 index 00000000000..9912f1cc1f8 --- /dev/null +++ b/.changeset/brave-modules-skip.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/graphql-modules-preset': patch +--- + +Skip sources without a `location` when grouping sources by module, instead of throwing from `path.normalize`, and skip sources without a `document` AST when building each module's document. Generated output from the CLI is unchanged. diff --git a/packages/presets/graphql-modules/src/builder.ts b/packages/presets/graphql-modules/src/builder.ts index aa8a4bcc801..24cdb08981a 100644 --- a/packages/presets/graphql-modules/src/builder.ts +++ b/packages/presets/graphql-modules/src/builder.ts @@ -439,7 +439,7 @@ export function buildModule( defined.objects.push(name); collectFields(node, picks.objects); - if (node.interfaces?.length > 0) { + if ((node.interfaces?.length ?? 0) > 0) { withIsTypeOf.objects.push(name); } @@ -495,7 +495,7 @@ export function buildModule( pushUnique(extended.objects, name); - if (node.interfaces?.length > 0) { + if ((node.interfaces?.length ?? 0) > 0) { pushUnique(withIsTypeOf.objects, name); } diff --git a/packages/presets/graphql-modules/src/index.ts b/packages/presets/graphql-modules/src/index.ts index cafa6f5f169..d04ebc3f79b 100644 --- a/packages/presets/graphql-modules/src/index.ts +++ b/packages/presets/graphql-modules/src/index.ts @@ -10,7 +10,7 @@ export const preset: Types.OutputPreset = { buildGeneratesSection: options => { const { baseOutputDir } = options; const { baseTypesPath, encapsulateModuleTypes } = options.presetConfig; - const useGraphQLModules = getConfigValue(options?.presetConfig.useGraphQLModules, true); + const useGraphQLModules = options?.presetConfig.useGraphQLModules ?? true; const requireRootResolvers = getConfigValue(options?.presetConfig.requireRootResolvers, false); const useTypeImports = getConfigValue(options?.config.useTypeImports, false) || false; @@ -94,7 +94,9 @@ export const preset: Types.OutputPreset = { normalize(join(relativePath, baseTypesFilename)); const sources = sourcesByModuleMap[moduleName]; - const moduleDocument = concatAST(sources.map(source => source.document)); + const moduleDocument = concatAST( + sources.flatMap(source => (source.document ? [source.document] : [])), + ); const shouldDeclare = filename.endsWith('.d.ts'); @@ -125,7 +127,7 @@ export const preset: Types.OutputPreset = { schema.getQueryType()?.name, schema.getMutationType()?.name, schema.getSubscriptionType()?.name, - ].filter(Boolean), + ].filter((name): name is string => !!name), useTypeImports, }), }, diff --git a/packages/presets/graphql-modules/src/utils.ts b/packages/presets/graphql-modules/src/utils.ts index e9f57046095..0a5a4e88299 100644 --- a/packages/presets/graphql-modules/src/utils.ts +++ b/packages/presets/graphql-modules/src/utils.ts @@ -182,6 +182,10 @@ export function groupSourcesByModule( const grouped: Record = {}; for (const source of sources) { + if (!source.location) { + continue; + } + const relativePath = getRelativePath(source.location, basePath); if (relativePath) { From c6ea56ec5c7029476d22511eaceff80713b55b76 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 26 Sep 2026 13:41:43 +0000 Subject: [PATCH 2/3] [visitor-plugin-common] fix: return non-nullable getConfigValue result when given a default (#4683) `getConfigValue` inferred `T` from both arguments, so a nullable config value made the result nullable even with a non-nullable default. Type `value` as `T | null | undefined` so `T` comes from the default. Under `strict: true` this fixes the two TS2345 errors in base-documents-visitor.ts. With `strictNullChecks` off (current master) the signature is unchanged. graphql-modules goes back to `getConfigValue` for `useGraphQLModules` instead of `?? true`. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XSMiQQc6YQZUo1EajQncWL eddeee888:oss:issue-fix --- .changeset/wide-config-values.md | 5 +++++ packages/plugins/other/visitor-plugin-common/src/utils.ts | 2 +- packages/presets/graphql-modules/src/index.ts | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/wide-config-values.md diff --git a/.changeset/wide-config-values.md b/.changeset/wide-config-values.md new file mode 100644 index 00000000000..6c011d95371 --- /dev/null +++ b/.changeset/wide-config-values.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/visitor-plugin-common': patch +--- + +Type `getConfigValue`'s `value` parameter as `T | null | undefined`, so the result is non-nullable when a non-nullable default is given. diff --git a/packages/plugins/other/visitor-plugin-common/src/utils.ts b/packages/plugins/other/visitor-plugin-common/src/utils.ts index 7a5edb4466d..55e85b6ca65 100644 --- a/packages/plugins/other/visitor-plugin-common/src/utils.ts +++ b/packages/plugins/other/visitor-plugin-common/src/utils.ts @@ -37,7 +37,7 @@ import type { ScalarsMap, } from './types.js'; -export const getConfigValue = (value: T, defaultValue: T): T => { +export const getConfigValue = (value: T | null | undefined, defaultValue: T): T => { if (value === null || value === undefined) { return defaultValue; } diff --git a/packages/presets/graphql-modules/src/index.ts b/packages/presets/graphql-modules/src/index.ts index d04ebc3f79b..c972859df32 100644 --- a/packages/presets/graphql-modules/src/index.ts +++ b/packages/presets/graphql-modules/src/index.ts @@ -10,7 +10,7 @@ export const preset: Types.OutputPreset = { buildGeneratesSection: options => { const { baseOutputDir } = options; const { baseTypesPath, encapsulateModuleTypes } = options.presetConfig; - const useGraphQLModules = options?.presetConfig.useGraphQLModules ?? true; + const useGraphQLModules = getConfigValue(options?.presetConfig.useGraphQLModules, true); const requireRootResolvers = getConfigValue(options?.presetConfig.requireRootResolvers, false); const useTypeImports = getConfigValue(options?.config.useTypeImports, false) || false; From 97f8cac45b7bd618516db8d296fb3f4f8ac7f120 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 26 Sep 2026 13:41:49 +0000 Subject: [PATCH 3/3] [graphql-modules-preset] fix: narrow rootTypes with a typeof guard (#4683) Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01XSMiQQc6YQZUo1EajQncWL eddeee888:oss:issue-fix --- packages/presets/graphql-modules/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/presets/graphql-modules/src/index.ts b/packages/presets/graphql-modules/src/index.ts index c972859df32..a48af6d5556 100644 --- a/packages/presets/graphql-modules/src/index.ts +++ b/packages/presets/graphql-modules/src/index.ts @@ -127,7 +127,7 @@ export const preset: Types.OutputPreset = { schema.getQueryType()?.name, schema.getMutationType()?.name, schema.getSubscriptionType()?.name, - ].filter((name): name is string => !!name), + ].filter((name): name is string => typeof name === 'string'), useTypeImports, }), },