From df48e30691d612d69f5d7611c63623e0ecf4f5df Mon Sep 17 00:00:00 2001 From: Francesco Novy Date: Thu, 27 Aug 2026 10:19:10 +0200 Subject: [PATCH] fix(node): Build-time instrument the ESM build of graphql MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The graphql orchestrion config only listed graphql's CommonJS file paths (`language/parser.js`, ...). graphql ships dual CJS/ESM per-file builds and the orchestrion matcher compares `filePath` exactly, so bundlers resolving graphql's ESM build (webpack with `outputModule`, vite, rollup, rolldown) never matched and left graphql uninstrumented at build time — the app ran but produced no graphql spans. Node's native ESM resolver ignores the `module` field and loads graphql's CJS build, so the runtime `--import` path (and the node-integration-tests) were unaffected; this gap only hit the bundler plugin path. Mirror the existing dual-path pattern from the `openai` config: emit one entry per built file (`.js` for `require`, `.mjs` for `import`). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../src/orchestrion/config/graphql.ts | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/server-utils/src/orchestrion/config/graphql.ts b/packages/server-utils/src/orchestrion/config/graphql.ts index d6eaabd2da5b..2dff843c8d1e 100644 --- a/packages/server-utils/src/orchestrion/config/graphql.ts +++ b/packages/server-utils/src/orchestrion/config/graphql.ts @@ -5,22 +5,25 @@ import { getModuleNames } from './module-names'; // `parse`/`validate`/`execute` are top-level named `function` declarations in graphql's compiled // files, stable across the supported majors, so `functionName` matches. `execute` returns // `PromiseOrValue`, so `Auto` covers both async (settles on `asyncEnd`) and sync (`end`) schemas. +// graphql ships dual CJS/ESM and the matcher compares `filePath` exactly, hence one entry per built +// file (`.js` for `require`, `.mjs` for `import`) — a bundler resolving the ESM build (e.g. webpack +// with `outputModule`) would otherwise never be transformed. export const graphqlConfig = [ - { + ...['language/parser.js', 'language/parser.mjs'].map(filePath => ({ channelName: 'parse', - module: { name: 'graphql', versionRange: '>=14.0.0 <17', filePath: 'language/parser.js' }, - functionQuery: { functionName: 'parse', kind: 'Sync' }, - }, - { + module: { name: 'graphql', versionRange: '>=14.0.0 <17', filePath }, + functionQuery: { functionName: 'parse', kind: 'Sync' as const }, + })), + ...['validation/validate.js', 'validation/validate.mjs'].map(filePath => ({ channelName: 'validate', - module: { name: 'graphql', versionRange: '>=14.0.0 <17', filePath: 'validation/validate.js' }, - functionQuery: { functionName: 'validate', kind: 'Sync' }, - }, - { + module: { name: 'graphql', versionRange: '>=14.0.0 <17', filePath }, + functionQuery: { functionName: 'validate', kind: 'Sync' as const }, + })), + ...['execution/execute.js', 'execution/execute.mjs'].map(filePath => ({ channelName: 'execute', - module: { name: 'graphql', versionRange: '>=14.0.0 <17', filePath: 'execution/execute.js' }, - functionQuery: { functionName: 'execute', kind: 'Auto' }, - }, + module: { name: 'graphql', versionRange: '>=14.0.0 <17', filePath }, + functionQuery: { functionName: 'execute', kind: 'Auto' as const }, + })), ] satisfies InstrumentationConfig[]; export const graphqlChannels = {