From be69e9d1a9c234061754a1922b8b961ec80a2fcb Mon Sep 17 00:00:00 2001 From: Eddy Nguyen Date: Sun, 27 Sep 2026 10:47:56 +1000 Subject: [PATCH] [graphql-modules-preset] fix: skip sources without a location or document under strict mode (#4683) (#10993) --- .changeset/brave-modules-skip.md | 5 +++++ .changeset/wide-config-values.md | 5 +++++ packages/plugins/other/visitor-plugin-common/src/utils.ts | 2 +- packages/presets/graphql-modules/src/builder.ts | 4 ++-- packages/presets/graphql-modules/src/index.ts | 6 ++++-- packages/presets/graphql-modules/src/utils.ts | 4 ++++ 6 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 .changeset/brave-modules-skip.md create mode 100644 .changeset/wide-config-values.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/.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/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..a48af6d5556 100644 --- a/packages/presets/graphql-modules/src/index.ts +++ b/packages/presets/graphql-modules/src/index.ts @@ -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 => typeof name === 'string'), 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) {