From 62394e54857bec5628de992bbea884c51948ad07 Mon Sep 17 00:00:00 2001 From: Liz Kenyon Date: Mon, 20 Oct 2025 15:23:20 -0500 Subject: [PATCH] Add file extensions to generated import paths for Node16/NodeNext compatibility MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes TypeScript compilation errors for users with Node16/NodeNext module resolution who were getting "Cannot find module './admin.types'" errors when building projects using generated GraphQL types Closes #2873 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .changeset/old-bats-lay.md | 5 +++++ packages/api-clients/api-codegen-preset/src/preset.ts | 8 +++++++- .../api-codegen-preset/src/tests/preset.test.ts | 8 ++++---- 3 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 .changeset/old-bats-lay.md diff --git a/.changeset/old-bats-lay.md b/.changeset/old-bats-lay.md new file mode 100644 index 0000000000..6156c9df10 --- /dev/null +++ b/.changeset/old-bats-lay.md @@ -0,0 +1,5 @@ +--- +'@shopify/api-codegen-preset': patch +--- + +Fixed TypeScript module resolution error by including file extensions (.d.ts or .ts) in generated import paths to support Node16/NodeNext module resolution strategies. diff --git a/packages/api-clients/api-codegen-preset/src/preset.ts b/packages/api-clients/api-codegen-preset/src/preset.ts index b3f74f7f2b..b8f35845a3 100644 --- a/packages/api-clients/api-codegen-preset/src/preset.ts +++ b/packages/api-clients/api-codegen-preset/src/preset.ts @@ -3,13 +3,19 @@ import {preset as hydrogenPreset} from '@shopify/graphql-codegen'; import {type ShopifyApiPresetConfig} from './types'; import {apiConfigs} from './helpers/api-configs'; +import {getOutputFiles} from './helpers/get-output-files'; export const preset: Types.OutputPreset = { buildGeneratesSection: (options) => { const apiType = options.presetConfig.apiType; const {interfaceExtension, module, presetConfigs} = apiConfigs[apiType]; - const typesFile = apiConfigs[apiType].typesFile; + + // Determine if the output file is a declaration file + const isDts = options.baseOutputDir.endsWith('.d.ts'); + + // Get the correct filename with extension (.d.ts or .ts) + const {typesFile} = getOutputFiles(apiType, isDts); return hydrogenPreset.buildGeneratesSection({ ...options, diff --git a/packages/api-clients/api-codegen-preset/src/tests/preset.test.ts b/packages/api-clients/api-codegen-preset/src/tests/preset.test.ts index 4d30726bd0..3991cae923 100644 --- a/packages/api-clients/api-codegen-preset/src/tests/preset.test.ts +++ b/packages/api-clients/api-codegen-preset/src/tests/preset.test.ts @@ -34,7 +34,7 @@ describe('Preset', () => { // Imports Admin API expect(generatedCode).toMatch( - `import type * as AdminTypes from './admin.types';`, + `import type * as AdminTypes from './admin.types.d.ts';`, ); // Uses Pick<...> @@ -59,7 +59,7 @@ describe('Preset', () => { .toBe(`/* eslint-disable eslint-comments/disable-enable-pair */ /* eslint-disable eslint-comments/no-unlimited-disable */ /* eslint-disable */ -import type * as AdminTypes from './admin.types'; +import type * as AdminTypes from './admin.types.d.ts'; export type TestQueryQueryVariables = AdminTypes.Exact<{ [key: string]: never; }>; @@ -100,7 +100,7 @@ declare module '@shopify/admin-api-client' { )!.content; expect(generatedCode).toMatch( - "import type * as AdminTypes from './admin.types';", + "import type * as AdminTypes from './admin.types.d.ts';", ); }); @@ -116,7 +116,7 @@ declare module '@shopify/admin-api-client' { )!.content; expect(generatedCode).toMatch( - "import * as AdminTypes from './admin.types';", + "import * as AdminTypes from './admin.types.ts';", ); }); });