{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * TracingChannel integration.\n *\n * GraphQL.js publishes lifecycle events on a set of named tracing channels\n * that application performance monitoring (APM) tools can subscribe to in\n * order to observe parse, validate, execute, subscribe, and resolver behavior,\n * plus selected executor internals. At module load time GraphQL.js resolves\n * `node:diagnostics_channel` itself so APMs do not need to interact with the\n * GraphQL API to enable tracing. On runtimes that do not expose\n * `node:diagnostics_channel` (e.g., browsers) the load silently no-ops and\n * emission sites short-circuit.\n *\n * Within the tracing context types, `error` means the traced JavaScript call\n * threw or rejected; it does not mean every `GraphQLError` returned by\n * GraphQL.js. Some channels complete normally and publish GraphQL errors on\n * `result`. Resolver errors can appear both as `message.error` on\n * `graphql:resolve` and as formatted errors in an enclosing execution or\n * subscription result. `graphql:parse`, `graphql:validate`, and\n * `graphql:execute:variableCoercion` are sync-only channels.\n * @category Diagnostics\n */\n\nimport { isPromiseLike } from './jsutils/isPromise.ts';\nimport type { Maybe } from './jsutils/Maybe.ts';\nimport type { ObjMap } from './jsutils/ObjMap.ts';\n\nimport type { GraphQLError } from './error/GraphQLError.ts';\n\nimport type {\n  DocumentNode,\n  OperationDefinitionNode,\n  OperationTypeNode,\n} from './language/ast.ts';\nimport type { Source } from './language/source.ts';\n\nimport type { GraphQLSchema } from './type/schema.ts';\n\nimport type { ExecutionResult } from './execution/Executor.ts';\nimport type { ExperimentalIncrementalExecutionResults } from './execution/incremental/IncrementalExecutor.ts';\nimport type { VariableValues } from './execution/values.ts';\n\n/**\n * Structural subset of `DiagnosticsChannel` sufficient for publishing and\n * subscriber gating. The `node:diagnostics_channel` `Channel` satisfies this.\n *\n * @internal\n */\nexport interface MinimalChannel<TMessage = unknown> {\n  readonly hasSubscribers?: boolean;\n  publish: (message: TMessage) => void;\n  runStores: <T, ContextType extends object>(\n    context: ContextType,\n    fn: (this: ContextType, ...args: Array<unknown>) => T,\n    thisArg?: unknown,\n    ...args: Array<unknown>\n  ) => T;\n}\n\n/**\n * Structural subset of the Node.js `TracingChannel` API. The\n * `node:diagnostics_channel` `TracingChannel` satisfies this by duck typing,\n * so GraphQL.js does not need a dependency on `@types/node` or on the runtime\n * itself.\n *\n * @internal\n */\nexport interface MinimalTracingChannel<TContext = unknown> {\n  // `undefined` accommodates runtimes (e.g. Bun) that ship `tracingChannel`\n  // without exposing the aggregate `hasSubscribers` getter.\n  readonly hasSubscribers: boolean | undefined;\n  readonly start: MinimalChannel<TContext>;\n  readonly end: MinimalChannel<TContext>;\n  readonly asyncStart: MinimalChannel<TContext>;\n  readonly asyncEnd: MinimalChannel<TContext>;\n  readonly error: MinimalChannel<TContext>;\n\n  traceSync: <T>(\n    fn: (...args: Array<unknown>) => T,\n    context: TContext extends object ? TContext : object,\n    thisArg?: unknown,\n    ...args: Array<unknown>\n  ) => T;\n}\n\ninterface DiagnosticsChannelModule {\n  tracingChannel: <TContext = unknown>(\n    name: string,\n  ) => MinimalTracingChannel<TContext>;\n}\n\n/** Context published on the sync-only `graphql:parse` channel. */\nexport interface GraphQLParseContext {\n  /** Source text or source object passed to the parser. */\n  source: string | Source;\n  /** Error thrown while parsing, when parsing fails. */\n  error?: unknown;\n  /** Parsed document, when parsing succeeds. */\n  result?: DocumentNode;\n}\n\n/** Context published on the sync-only `graphql:validate` channel. */\nexport interface GraphQLValidateContext {\n  /** Schema used for validation. */\n  schema: GraphQLSchema;\n  /** Parsed document being validated. */\n  document: DocumentNode;\n  /** Error thrown while validating, when validation fails abruptly. */\n  error?: unknown;\n  /** Validation errors returned by validation. */\n  result?: ReadonlyArray<GraphQLError>;\n}\n\n/**\n * Context published on `graphql:execute`.\n *\n * Returned results may contain GraphQL errors collected during execution.\n */\nexport interface GraphQLExecuteContext {\n  /** Schema used for execution. */\n  schema: GraphQLSchema;\n  /** Parsed document being executed. */\n  document: DocumentNode;\n  /** Raw variable values provided by the caller before coercion. */\n  rawVariableValues: Maybe<{ readonly [variable: string]: unknown }>;\n  /** Selected operation name, if one is available. */\n  operationName: string | undefined;\n  /** Selected operation type, if one is available. */\n  operationType: OperationTypeNode | undefined;\n  /** Error thrown or rejected while executing, when execution fails abruptly. */\n  error?: unknown;\n  /** Execution result returned by execution, including GraphQL errors. */\n  result?: ExecutionResult | ExperimentalIncrementalExecutionResults;\n}\n\n/**\n * Context published on `graphql:execute:rootSelectionSet`.\n *\n * Returned results may contain GraphQL errors collected during execution.\n */\nexport interface GraphQLExecuteRootSelectionSetContext {\n  /** Schema used for execution. */\n  schema: GraphQLSchema;\n  /** Parsed document being executed. */\n  document: DocumentNode;\n  /** Operation definition selected for execution. */\n  operation: OperationDefinitionNode;\n  /** Raw variable values provided by the caller before coercion. */\n  rawVariableValues: Maybe<{ readonly [variable: string]: unknown }>;\n  /** Selected operation name, if one is available. */\n  operationName: string | undefined;\n  /** Selected operation type. */\n  operationType: OperationTypeNode;\n  /** Error thrown or rejected while executing the root selection set. */\n  error?: unknown;\n  /**\n   * Execution result returned from the root selection set, including GraphQL\n   * errors.\n   */\n  result?: ExecutionResult | ExperimentalIncrementalExecutionResults;\n}\n\n/**\n * Context published on `graphql:execute:variableCoercion`.\n *\n * Coercion runs synchronously while execution arguments are validated, so only\n * the `start`/`end` (and, on an abrupt throw, `error`) lifecycle fires.\n * Ordinary variable coercion failures are returned on `result.errors`; when\n * execution is invoked through APIs such as `execute()` or `subscribe()`, they\n * surface as GraphQL result errors rather than as the tracing `error`\n * lifecycle event.\n */\nexport interface GraphQLExecuteVariableCoercionContext {\n  /** Schema used for variable coercion. */\n  schema: GraphQLSchema;\n  /** Parsed document being executed. */\n  document: DocumentNode;\n  /** Operation definition whose variables are being coerced. */\n  operation: OperationDefinitionNode;\n  /** Raw variable values provided by the caller before coercion. */\n  rawVariableValues: Maybe<{ readonly [variable: string]: unknown }>;\n  /** Selected operation name, if one is available. */\n  operationName: string | undefined;\n  /** Selected operation type. */\n  operationType: OperationTypeNode;\n  /** Error thrown while coercing variables, when coercion fails abruptly. */\n  error?: unknown;\n  /** Coerced variable values or coercion errors returned by coercion. */\n  result?:\n    | { variableValues: VariableValues }\n    | { errors: ReadonlyArray<GraphQLError> };\n}\n\n/**\n * Context published on `graphql:subscribe`.\n *\n * Subscription source resolver errors and invalid source stream results are\n * returned on `result` as ExecutionResult errors; they do not publish the\n * `error` lifecycle event unless subscription setup fails abruptly before\n * GraphQL can form a result.\n */\nexport interface GraphQLSubscribeContext {\n  /** Schema used for subscription execution. */\n  schema: GraphQLSchema;\n  /** Parsed subscription document. */\n  document: DocumentNode;\n  /** Raw variable values provided by the caller before coercion. */\n  rawVariableValues: Maybe<{ readonly [variable: string]: unknown }>;\n  /** Selected operation name, if one is available. */\n  operationName: string | undefined;\n  /** Selected operation type, if one is available. */\n  operationType: OperationTypeNode | undefined;\n  /** Error thrown or rejected while subscribing, when setup fails abruptly. */\n  error?: unknown;\n  /**\n   * Subscription response stream, or an ExecutionResult containing GraphQL\n   * errors.\n   */\n  result?: AsyncGenerator<ExecutionResult, void, void> | ExecutionResult;\n}\n\n/**\n * Context published on `graphql:resolve`.\n *\n * Resolver throws and rejections publish the `error` lifecycle event here.\n * The same failure may also be formatted into the enclosing execution or\n * subscription result.\n */\nexport interface GraphQLResolveContext {\n  /** Field name being resolved. */\n  fieldName: string;\n  /** Response alias for the field being resolved. */\n  alias: string;\n  /** Parent type name for the field being resolved. */\n  parentType: string;\n  /** Return type string for the field being resolved. */\n  fieldType: string;\n  /** Argument values passed to the resolver. */\n  args: ObjMap<unknown>;\n  /** Whether the field is using the default resolver. */\n  isDefaultResolver: boolean;\n  /** Response path for the field being resolved. */\n  fieldPath: string;\n  /** Error thrown or rejected by the resolver, when resolution fails. */\n  error?: unknown;\n  /** Value returned by the resolver, when resolution succeeds. */\n  result?: unknown;\n}\n\n/** Mapping from tracing channel name to the context type published on it. */\nexport interface GraphQLChannelContextByName {\n  /** Context published on `graphql:parse`. */\n  'graphql:parse': GraphQLParseContext;\n  /** Context published on `graphql:validate`. */\n  'graphql:validate': GraphQLValidateContext;\n  /** Context published on `graphql:execute`. */\n  'graphql:execute': GraphQLExecuteContext;\n  /** Context published on `graphql:execute:variableCoercion`. */\n  'graphql:execute:variableCoercion': GraphQLExecuteVariableCoercionContext;\n  /** Context published on `graphql:execute:rootSelectionSet`. */\n  'graphql:execute:rootSelectionSet': GraphQLExecuteRootSelectionSetContext;\n  /** Context published on `graphql:subscribe`. */\n  'graphql:subscribe': GraphQLSubscribeContext;\n  /** Context published on `graphql:resolve`. */\n  'graphql:resolve': GraphQLResolveContext;\n}\n\n/**\n * The collection of tracing channels GraphQL.js emits on. Application\n * performance monitoring (APM) tools subscribe to these by name on their own\n * `node:diagnostics_channel` import; both paths land on the same channel\n * instance because `tracingChannel(name)` is cached by name.\n */\nexport interface GraphQLChannels {\n  /** Tracing channel for `graphql:execute`. */\n  execute: MinimalTracingChannel<GraphQLExecuteContext>;\n  /** Tracing channel for `graphql:execute:variableCoercion`. */\n  executeVariableCoercion: MinimalTracingChannel<GraphQLExecuteVariableCoercionContext>;\n  /** Tracing channel for `graphql:execute:rootSelectionSet`. */\n  executeRootSelectionSet: MinimalTracingChannel<GraphQLExecuteRootSelectionSetContext>;\n  /** Tracing channel for `graphql:parse`. */\n  parse: MinimalTracingChannel<GraphQLParseContext>;\n  /** Tracing channel for `graphql:validate`. */\n  validate: MinimalTracingChannel<GraphQLValidateContext>;\n  /** Tracing channel for `graphql:resolve`. */\n  resolve: MinimalTracingChannel<GraphQLResolveContext>;\n  /** Tracing channel for `graphql:subscribe`. */\n  subscribe: MinimalTracingChannel<GraphQLSubscribeContext>;\n}\n\nfunction resolveDiagnosticsChannel(): DiagnosticsChannelModule | undefined {\n  let dc: DiagnosticsChannelModule | undefined;\n  try {\n    const processRef = (\n      globalThis as {\n        process?: { getBuiltinModule?: (id: string) => unknown };\n      }\n    ).process;\n    if (\n      // eslint-disable-next-line n/no-unsupported-features/node-builtins\n      typeof processRef?.getBuiltinModule === 'function'\n    ) {\n      // eslint-disable-next-line n/no-unsupported-features/node-builtins\n      dc = processRef.getBuiltinModule(\n        'node:diagnostics_channel',\n      ) as DiagnosticsChannelModule;\n    }\n    /* node:coverage ignore next 3 */\n  } catch {\n    // diagnostics_channel not available on this runtime; tracing is a no-op.\n  }\n  return dc;\n}\n\nconst dc = resolveDiagnosticsChannel();\n\n/**\n * Per-channel handles, resolved once at module load. `undefined` when\n * `node:diagnostics_channel` isn't available. Emission sites read these\n * directly to keep the no-subscriber fast path to a single property access\n * plus a `hasSubscribers` check (no function calls, no closures).\n *\n * @internal\n */\nexport const parseChannel:\n  | MinimalTracingChannel<GraphQLParseContext>\n  | undefined = dc?.tracingChannel('graphql:parse');\n/** @internal */\nexport const validateChannel:\n  | MinimalTracingChannel<GraphQLValidateContext>\n  | undefined = dc?.tracingChannel('graphql:validate');\n/** @internal */\nexport const executeChannel:\n  | MinimalTracingChannel<GraphQLExecuteContext>\n  | undefined = dc?.tracingChannel('graphql:execute');\n/** @internal */\nexport const executeVariableCoercionChannel:\n  | MinimalTracingChannel<GraphQLExecuteVariableCoercionContext>\n  | undefined = dc?.tracingChannel('graphql:execute:variableCoercion');\n/** @internal */\nexport const executeRootSelectionSetChannel:\n  | MinimalTracingChannel<GraphQLExecuteRootSelectionSetContext>\n  | undefined = dc?.tracingChannel('graphql:execute:rootSelectionSet');\n/** @internal */\nexport const subscribeChannel:\n  | MinimalTracingChannel<GraphQLSubscribeContext>\n  | undefined = dc?.tracingChannel('graphql:subscribe');\n/** @internal */\nexport const resolveChannel:\n  | MinimalTracingChannel<GraphQLResolveContext>\n  | undefined = dc?.tracingChannel('graphql:resolve');\n\nconst SUB_CHANNEL_KEYS: ReadonlyArray<\n  'start' | 'end' | 'asyncStart' | 'asyncEnd' | 'error'\n> = ['start', 'end', 'asyncStart', 'asyncEnd', 'error'];\n\n/**\n * Whether emission sites should publish to `channel`. Trusts the\n * `TracingChannel.hasSubscribers` aggregate when the runtime exposes it; if\n * the getter is missing (e.g. Bun's `node:diagnostics_channel`, where\n * `tracingChannel.hasSubscribers` is `undefined`), falls back to checking\n * each of the five underlying lifecycle channels so a subscriber attached\n * via `tracingChannel.subscribe(handlers)` is still observed.\n *\n * @internal\n */\nexport function shouldTrace<TContext = unknown>(\n  channel: MinimalTracingChannel<TContext> | undefined,\n): channel is MinimalTracingChannel<TContext> {\n  if (channel == null) {\n    return false;\n  }\n  const aggregate = channel.hasSubscribers;\n  if (aggregate !== undefined) {\n    return aggregate;\n  }\n  // Bun-only fallback, exercised by integrationTests/diagnostics-bun.\n  for (const key of SUB_CHANNEL_KEYS) {\n    if (channel[key].hasSubscribers) {\n      return true;\n    }\n  }\n  return false;\n}\n\ninterface TraceLifecycleContext {\n  error?: unknown;\n  result?: unknown;\n}\n\ntype TraceStartContext<TContext extends TraceLifecycleContext> = Omit<\n  TContext,\n  'error' | 'result'\n>;\n\n/**\n * Publish a traced call that may complete synchronously or with a promise.\n * Caller has already verified that a subscriber is attached. On normal\n * completion, `result` is attached before the terminal `end` or `asyncEnd`\n * event. When the traced call throws or rejects, `error` is attached, the\n * `error` sub-channel fires, and the terminal `end` or `asyncEnd` event is\n * published before the original failure is propagated.\n *\n * @internal\n */\nexport function traceMixed<TResult, TContext extends TraceLifecycleContext>(\n  channel: MinimalTracingChannel<TContext>,\n  contextInput: TraceStartContext<TContext>,\n  fn: () => TResult,\n): TResult {\n  const context = contextInput as TContext;\n\n  return channel.start.runStores(context, () => {\n    let result: TResult;\n    try {\n      result = fn();\n    } catch (err) {\n      context.error = err;\n      channel.error.publish(context);\n      channel.end.publish(context);\n      throw err;\n    }\n\n    if (!isPromiseLike(result)) {\n      context.result = result;\n      channel.end.publish(context);\n      return result;\n    }\n\n    channel.end.publish(context);\n\n    return result.then(\n      (value) => {\n        context.result = value;\n        channel.asyncStart.publish(context);\n        channel.asyncEnd.publish(context);\n        return value;\n      },\n      (err: unknown) => {\n        context.error = err;\n        channel.error.publish(context);\n        channel.asyncStart.publish(context);\n        channel.asyncEnd.publish(context);\n        throw err;\n      },\n    ) as TResult;\n  });\n}\n"]}