diff --git a/.changeset/strict-client-preset.md b/.changeset/strict-client-preset.md new file mode 100644 index 00000000000..71eaaad8c71 --- /dev/null +++ b/.changeset/strict-client-preset.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/client-preset': patch +--- + +Fix type errors under `strict: true`. The preset now throws a clear error when `schemaAst` is missing from the preset options, and the babel plugin throws when a file has no filename. Both cases used to crash later with a less clear error. Generated output is unchanged. diff --git a/packages/presets/client/src/babel.ts b/packages/presets/client/src/babel.ts index f47c4bc86f5..f78ee80349f 100644 --- a/packages/presets/client/src/babel.ts +++ b/packages/presets/client/src/babel.ts @@ -1,9 +1,8 @@ import * as path from 'path'; import { buildSchema, parse } from 'graphql'; -import type { PluginObj, PluginPass } from '@babel/core'; +import type { NodePath, PluginObj, PluginPass } from '@babel/core'; import { declare } from '@babel/helper-plugin-utils'; import template from '@babel/template'; -import type { NodePath } from '@babel/traverse'; import type { Program } from '@babel/types'; import { ClientSideBaseVisitor } from '@graphql-codegen/visitor-plugin-common'; @@ -82,12 +81,11 @@ function getRelativeImportPath( artifactDirectory: string, fileToRequire = 'graphql', ): string { - if (state.file == null) { + const filename = state.file?.opts.filename; + if (!filename) { throw new Error('Babel state is missing expected file name'); } - const { filename } = state.file.opts; - const relative = path.relative(path.dirname(filename), path.resolve(artifactDirectory)); const relativeReference = relative.length === 0 || !relative.startsWith('.') ? './' : ''; diff --git a/packages/presets/client/src/fragment-masking-plugin.ts b/packages/presets/client/src/fragment-masking-plugin.ts index e9044330738..0b3ff6463fe 100644 --- a/packages/presets/client/src/fragment-masking-plugin.ts +++ b/packages/presets/client/src/fragment-masking-plugin.ts @@ -146,7 +146,7 @@ export const plugin: PluginFunction<{ unmaskFunctionName, emitLegacyCommonJSImports, importExtension, - isStringDocumentMode, + isStringDocumentMode = false, }, _info, ) => { diff --git a/packages/presets/client/src/index.ts b/packages/presets/client/src/index.ts index 9ca459ee356..11f8752d8e0 100644 --- a/packages/presets/client/src/index.ts +++ b/packages/presets/client/src/index.ts @@ -144,9 +144,13 @@ export const preset: Types.OutputPreset = { '[client-preset] providing typescript-based `plugins` with `preset: "client" leads to duplicated generated types', ); } + if (!options.schemaAst) { + throw new Error('[client-preset] missing `schemaAst` in preset options'); + } + const isPersistedOperations = !!options.presetConfig?.persistedDocuments; if (options.config.nullability?.errorHandlingClient) { - options.schemaAst = await semanticToStrict(options.schemaAst!); + options.schemaAst = await semanticToStrict(options.schemaAst); options.schema = parse(printSchema(options.schemaAst)); } @@ -282,7 +286,7 @@ export const preset: Types.OutputPreset = { importExtension: options.config.importExtension, }); - if (isMaskingFragments === true) { + if (fragmentMaskingConfig !== null) { const fragmentMaskingArtifactFileExtension = '.ts'; reexports.push('fragment-masking'); diff --git a/packages/presets/client/src/persisted-documents.ts b/packages/presets/client/src/persisted-documents.ts index 356fb02d6de..49840d2e406 100644 --- a/packages/presets/client/src/persisted-documents.ts +++ b/packages/presets/client/src/persisted-documents.ts @@ -41,21 +41,25 @@ export function normalizeAndPrintDocumentNode(documentNode: DocumentNode): strin if (field.directives?.some(directive => directive.name.value === CLIENT_DIRECTIVE_NAME)) { return null; } + return; }, [Kind.FRAGMENT_SPREAD](spread) { if (spread.directives?.some(directive => directive.name.value === CLIENT_DIRECTIVE_NAME)) { return null; } + return; }, [Kind.INLINE_FRAGMENT](fragment) { if (fragment.directives?.some(directive => directive.name.value === CLIENT_DIRECTIVE_NAME)) { return null; } + return; }, [Kind.DIRECTIVE](directive) { if (directive.name.value === CONNECTION_DIRECTIVE_NAME) { return null; } + return; }, }); diff --git a/packages/presets/client/src/process-sources.ts b/packages/presets/client/src/process-sources.ts index c9b8e41b792..bcbb3460966 100644 --- a/packages/presets/client/src/process-sources.ts +++ b/packages/presets/client/src/process-sources.ts @@ -92,7 +92,7 @@ export function processSources( function fixLinebreaks(source: Types.DocumentFile) { const fixedSource = { ...source }; - fixedSource.rawSDL = source.rawSDL.replace(/\r\n/g, '\n'); + fixedSource.rawSDL = source.rawSDL?.replace(/\r\n/g, '\n'); return fixedSource; }