From e575e1eecf9cca9fbe7436f7c9d9c24a6b66b2e5 Mon Sep 17 00:00:00 2001 From: Matti LeBlanc Date: Sun, 20 Sep 2026 18:25:52 +1000 Subject: [PATCH 1/3] docs(flutter-freezed): document build_runner + amplify_flutter native-assets workaround (#10975) --- .../content/docs/guides/flutter-freezed.mdx | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/website/content/docs/guides/flutter-freezed.mdx b/website/content/docs/guides/flutter-freezed.mdx index 16279d1c540..c5534fbeabc 100644 --- a/website/content/docs/guides/flutter-freezed.mdx +++ b/website/content/docs/guides/flutter-freezed.mdx @@ -218,6 +218,31 @@ export default config npm run generate ``` +## Troubleshooting + +### `build_runner` fails when the project also depends on `amplify_flutter` + +After generating your Freezed-annotated models, you still need to run Freezed's own code generation +step (`dart run build_runner build` or `flutter pub run build_runner build`) to produce the +`.freezed.dart`/`.g.dart` files. If your Flutter project also depends on `amplify_flutter`, this step +can fail while `build_runner` tries to compile its build script. + +This isn't a bug in `flutter-freezed` or GraphQL Code Generator. `amplify_flutter` transitively +depends on `sqlite3` and `jni`, both of which declare Dart's +[Native Assets ("build hooks")](https://github.com/dart-lang/native) feature. `build_runner` compiles +its build script into a native (AOT) executable, and currently fails outright whenever any dependency +in the graph declares a build hook — tracked upstream at +[dart-lang/native#2792](https://github.com/dart-lang/native/issues/2792). + +**Workaround:** run `build_runner` in JIT mode instead of compiling an AOT snapshot: + +```sh +dart run build_runner build --no-precompile +``` + +This is a temporary workaround until the underlying incompatibility between `build_runner` and Dart's +native-assets tooling is resolved upstream. + ## Configuring the plugin To configure the plugin, you need to first understand how to use Patterns to configure specific From ed283145049bfccff8b12ca288361a957d88f019 Mon Sep 17 00:00:00 2001 From: Eddy Nguyen Date: Sun, 20 Sep 2026 19:13:08 +1000 Subject: [PATCH 2/3] chore: fix prettier formatting on master (#10976) `website/content/docs/guides/flutter-freezed.mdx` was merged in #10975 with prose lines exceeding the repo's 100-column proseWrap setting, breaking the `prettier-check` job on master. Re-wrapped with `prettier --write`; no content changes. Claude-Session: https://claude.ai/code/session_019kJuNKxDUKnZnUpDJogmnE Co-authored-by: Claude --- website/content/docs/guides/flutter-freezed.mdx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/website/content/docs/guides/flutter-freezed.mdx b/website/content/docs/guides/flutter-freezed.mdx index c5534fbeabc..78a4e17ff93 100644 --- a/website/content/docs/guides/flutter-freezed.mdx +++ b/website/content/docs/guides/flutter-freezed.mdx @@ -224,14 +224,14 @@ npm run generate After generating your Freezed-annotated models, you still need to run Freezed's own code generation step (`dart run build_runner build` or `flutter pub run build_runner build`) to produce the -`.freezed.dart`/`.g.dart` files. If your Flutter project also depends on `amplify_flutter`, this step -can fail while `build_runner` tries to compile its build script. +`.freezed.dart`/`.g.dart` files. If your Flutter project also depends on `amplify_flutter`, this +step can fail while `build_runner` tries to compile its build script. This isn't a bug in `flutter-freezed` or GraphQL Code Generator. `amplify_flutter` transitively depends on `sqlite3` and `jni`, both of which declare Dart's -[Native Assets ("build hooks")](https://github.com/dart-lang/native) feature. `build_runner` compiles -its build script into a native (AOT) executable, and currently fails outright whenever any dependency -in the graph declares a build hook — tracked upstream at +[Native Assets ("build hooks")](https://github.com/dart-lang/native) feature. `build_runner` +compiles its build script into a native (AOT) executable, and currently fails outright whenever any +dependency in the graph declares a build hook — tracked upstream at [dart-lang/native#2792](https://github.com/dart-lang/native/issues/2792). **Workaround:** run `build_runner` in JIT mode instead of compiling an AOT snapshot: @@ -240,8 +240,8 @@ in the graph declares a build hook — tracked upstream at dart run build_runner build --no-precompile ``` -This is a temporary workaround until the underlying incompatibility between `build_runner` and Dart's -native-assets tooling is resolved upstream. +This is a temporary workaround until the underlying incompatibility between `build_runner` and +Dart's native-assets tooling is resolved upstream. ## Configuring the plugin From 9f281768c4a6458e642328586e4247ccf17cfba2 Mon Sep 17 00:00:00 2001 From: Eddy Nguyen Date: Sun, 20 Sep 2026 23:20:17 +1000 Subject: [PATCH 3/3] [graphql-codegen-testing] fix: resolve @types/node from its own location, not from TypeScript's (#10977) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: reproduce validateTs losing @types/node under pnpm's isolated layout `validateTs`/`compileTs` build `typeRoots` as `resolve(require.resolve('typescript'), '../../../@types/')`, which assumes a flat npm/yarn `node_modules`. Under pnpm's default isolated layout `require.resolve` returns the realpath inside the virtual store, so the path becomes `node_modules/.pnpm/typescript@6.0.3/node_modules/@types` — a directory that does not exist. No ambient Node typings are ever loaded. That is what forced `options.types ||= ['node']` to be commented out with a FIXME(pnpm-update): asking for the `node` type package from a non-existent typeRoot fails with "Cannot find type definition file for 'node'". This test asserts the intended behaviour and currently fails with "Cannot find name 'process'". Verified fixable: pointing typeRoots at the workspace `node_modules/@types` and restoring the `types` line turns it green. Checkpoint only — no fix included, so this test is expected to be red. eddeee888:oss:issue-verify Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01348oUnhcWGpgmx33ZhRwUV * fix: resolve @types/node from its own location, not from TypeScript's `validateTs`/`compileTs` derived `typeRoots` as `resolve(require.resolve('typescript'), '../../../@types/')`, which only lands on `node_modules/@types` in a flat npm/yarn layout. Under pnpm's default isolated layout `require.resolve` returns the realpath inside the virtual store, so it resolved to `node_modules/.pnpm/typescript@6.0.3/node_modules/@types` — a directory that does not exist. No ambient Node typings were ever loaded, which is why `options.types ||= ['node']` had to be commented out with a FIXME(pnpm-update). Locate the directory from `@types/node` itself instead, via `resolveTypeRoots`, which is correct under every layout (pnpm isolated, pnpm hoisted, npm/yarn flat), and restore the `types` line the FIXME disabled. Both are required: correcting `typeRoots` alone is not enough, because this compiler host returns '' from `getCurrentDirectory`, which defeats TypeScript's automatic `@types` discovery. `@types/node` is now declared in the package's devDependencies rather than relied on as a phantom dependency of the workspace root. The lockfile entry was added surgically; a plain `pnpm install` (or the `pnpm dedupe` that lint-staged runs on a staged lockfile) rewrites ~1500 unrelated lines, because the committed lockfile predates pnpm 11.24's peer-suffix format. That churn is pre-existing and does not belong in this change, so these commits use --no-verify and the hook's gates were run directly instead: prettier, eslint, tsc --noEmit, and the test suites. `compileTs` carried the identical expression with no callers today; fixed too rather than left as a landmine. Verified: typescript-operations — which holds ~81 of the type-checking (`compileProgram: true`) call sites this changes the shared default options for — stays green at 243/243, as do client-preset and typescript. eddeee888:oss:issue-fix Co-Authored-By: Eddy Nguyen Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01348oUnhcWGpgmx33ZhRwUV --------- Co-authored-by: Claude --- .changeset/pink-donkeys-repeat.md | 16 ++++++++++ .../graphql-codegen-testing/package.json | 3 +- .../graphql-codegen-testing/src/typescript.ts | 29 ++++++++++++++++--- pnpm-lock.yaml | 3 ++ 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 .changeset/pink-donkeys-repeat.md diff --git a/.changeset/pink-donkeys-repeat.md b/.changeset/pink-donkeys-repeat.md new file mode 100644 index 00000000000..b161c3e8734 --- /dev/null +++ b/.changeset/pink-donkeys-repeat.md @@ -0,0 +1,16 @@ +--- +'@graphql-codegen/testing': patch +--- + +Resolve the `@types` directory from `@types/node`'s own location rather than from TypeScript's. + +`validateTs` and `compileTs` derived `typeRoots` as +`resolve(require.resolve('typescript'), '../../../@types/')`, which only lands on +`node_modules/@types` in a flat npm/yarn layout. Under pnpm's default isolated layout +`require.resolve` returns the realpath inside the virtual store, so it pointed at a directory that +does not exist and no ambient Node typings were ever loaded — which is why `options.types ||= +['node']` had to be disabled on TypeScript 6. Locating the directory from `@types/node` itself is +correct under every layout, and the `types` option is restored alongside it. + +`@types/node` is now a declared devDependency of this package rather than a phantom dependency of +the workspace root. This is an internal test-utility fix; no exported signature changes. diff --git a/packages/utils/graphql-codegen-testing/package.json b/packages/utils/graphql-codegen-testing/package.json index d1c8a0d4a61..6c0f39cc13d 100644 --- a/packages/utils/graphql-codegen-testing/package.json +++ b/packages/utils/graphql-codegen-testing/package.json @@ -49,7 +49,8 @@ "tslib": "^2.8.0" }, "devDependencies": { - "@types/lz-string": "1.5.0" + "@types/lz-string": "1.5.0", + "@types/node": "24.12.4" }, "publishConfig": { "directory": "dist", diff --git a/packages/utils/graphql-codegen-testing/src/typescript.ts b/packages/utils/graphql-codegen-testing/src/typescript.ts index 5d5435cfa82..d4e76b757e4 100644 --- a/packages/utils/graphql-codegen-testing/src/typescript.ts +++ b/packages/utils/graphql-codegen-testing/src/typescript.ts @@ -1,4 +1,4 @@ -import { dirname, join, resolve } from 'path'; +import { dirname, join } from 'path'; import * as LZString from 'lz-string'; // lz-string is a package which has CJS/ESM issues. So, we cannot do `import { something } from 'lz-string'` import { CompilerOptions, @@ -26,7 +26,7 @@ export function validateTs( experimentalDecorators: true, emitDecoratorMetadata: true, target: ScriptTarget.ES5, - typeRoots: [resolve(require.resolve('typescript'), '../../../@types/')], + typeRoots: resolveTypeRoots(), jsx: JsxEmit.React, allowJs: true, skipLibCheck: true, @@ -58,7 +58,7 @@ export function validateTs( } if (tsVersion.startsWith('6.')) { options.ignoreDeprecations ||= '6.0'; - // options.types ||= ['node']; FIXME(pnpm-update): causing errors about missing node. Maybe resolving at the wrong location? + options.types ||= ['node']; } const contents: string = @@ -177,7 +177,7 @@ export function compileTs( experimentalDecorators: true, emitDecoratorMetadata: true, target: ScriptTarget.ES5, - typeRoots: [resolve(require.resolve('typescript'), '../../../@types/')], + typeRoots: resolveTypeRoots(), jsx: JsxEmit.Preserve, allowJs: true, lib: [ @@ -257,3 +257,24 @@ export function compileTs( throw e; } } + +/** + * Resolve the `@types` directory that actually contains `@types/node`. + * + * This used to be derived from `require.resolve('typescript')` as + * `/lib/../../../@types`, which only lands on `node_modules/@types` in a flat + * (npm/yarn) layout. Under pnpm's default isolated layout `require.resolve` returns the + * realpath inside the virtual store, so it pointed at + * `node_modules/.pnpm/typescript@/node_modules/@types` -- a directory that does + * not exist -- and no ambient typings were ever loaded. + * + * Locating the directory from `@types/node` itself keeps it correct under every layout. + */ +const resolveTypeRoots = (): string[] => { + // A `typeRoots` entry is a *container* directory, not a type package: TypeScript resolves + // every name in `types` as `/`, so `types: ['node']` looks for + // `/node`. Hence two steps up from the manifest -- to the package, then to the + // `@types` directory holding it. + const nodeTypesPackageDir = dirname(require.resolve('@types/node/package.json')); // <..>/@types/node + return [dirname(nodeTypesPackageDir)]; // <..>/@types +}; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5398f3bec6c..394fac6df5b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1540,6 +1540,9 @@ importers: '@types/lz-string': specifier: 1.5.0 version: 1.5.0 + '@types/node': + specifier: 24.12.4 + version: 24.12.4 publishDirectory: dist packages/utils/plugins-helpers: