From 8b3ed16cd07fb1e264f9afac369917d9e4e21509 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 11:24:26 +0100 Subject: [PATCH 01/14] useHiveConsole --- packages/runtime/package.json | 2 +- packages/runtime/src/createGatewayRuntime.ts | 11 ++--- packages/runtime/src/getReportingPlugin.ts | 6 +-- .../runtime/src/plugins/useHiveConsole.ts | 24 ++++++++++ packages/runtime/src/types.ts | 8 +++- yarn.lock | 46 +++---------------- 6 files changed, 46 insertions(+), 51 deletions(-) create mode 100644 packages/runtime/src/plugins/useHiveConsole.ts diff --git a/packages/runtime/package.json b/packages/runtime/package.json index be224f563..be0f07dd9 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -49,10 +49,10 @@ "@envelop/generic-auth": "^9.0.0", "@graphql-hive/core": "^0.10.0", "@graphql-hive/logger-json": "workspace:^", + "@graphql-hive/yoga": "^0.41.0", "@graphql-mesh/cross-helpers": "^0.4.10", "@graphql-mesh/fusion-runtime": "workspace:^", "@graphql-mesh/hmac-upstream-signature": "workspace:^", - "@graphql-mesh/plugin-hive": "^0.104.0", "@graphql-mesh/plugin-response-cache": "^0.104.0", "@graphql-mesh/transport-common": "workspace:^", "@graphql-mesh/types": "^0.104.0", diff --git a/packages/runtime/src/createGatewayRuntime.ts b/packages/runtime/src/createGatewayRuntime.ts index ed0749359..69bbe3754 100644 --- a/packages/runtime/src/createGatewayRuntime.ts +++ b/packages/runtime/src/createGatewayRuntime.ts @@ -21,7 +21,6 @@ import { UnifiedGraphManager, } from '@graphql-mesh/fusion-runtime'; import { useHmacUpstreamSignature } from '@graphql-mesh/hmac-upstream-signature'; -import useMeshHive from '@graphql-mesh/plugin-hive'; import useMeshResponseCache from '@graphql-mesh/plugin-response-cache'; import { TransportContext } from '@graphql-mesh/transport-common'; import type { @@ -96,6 +95,7 @@ import { useCustomAgent } from './plugins/useCustomAgent'; import { useDelegationPlanDebug } from './plugins/useDelegationPlanDebug'; import { useDemandControl } from './plugins/useDemandControl'; import { useFetchDebug } from './plugins/useFetchDebug'; +import useHiveConsole from './plugins/useHiveConsole'; import { usePropagateHeaders } from './plugins/usePropagateHeaders'; import { useRequestId } from './plugins/useRequestId'; import { useSubgraphExecuteDebug } from './plugins/useSubgraphExecuteDebug'; @@ -191,10 +191,8 @@ export function createGatewayRuntime< let contextBuilder: (context: T) => MaybePromise; let readinessChecker: () => MaybePromise; let getExecutor: (() => MaybePromise) | undefined; - const { name: reportingTarget, plugin: registryPlugin } = getReportingPlugin( - config, - configContext, - ); + const { name: reportingTarget, plugin: registryPlugin } = + getReportingPlugin(config, configContext) || {}; let persistedDocumentsPlugin: GatewayPlugin = {}; if ( config.reporting?.type !== 'hive' && @@ -202,8 +200,9 @@ export function createGatewayRuntime< 'type' in config.persistedDocuments && config.persistedDocuments?.type === 'hive' ) { - persistedDocumentsPlugin = useMeshHive({ + persistedDocumentsPlugin = useHiveConsole({ ...configContext, + enabled: false, // disables only usage reporting logger: configContext.logger.child({ plugin: 'Hive Persisted Documents', }), diff --git a/packages/runtime/src/getReportingPlugin.ts b/packages/runtime/src/getReportingPlugin.ts index 2940fa53c..bda6a53d4 100644 --- a/packages/runtime/src/getReportingPlugin.ts +++ b/packages/runtime/src/getReportingPlugin.ts @@ -1,5 +1,5 @@ -import useMeshHive from '@graphql-mesh/plugin-hive'; import { useApolloUsageReport } from '@graphql-yoga/plugin-apollo-usage-report'; +import useHiveConsole from './plugins/useHiveConsole'; import type { GatewayConfig, GatewayConfigContext, @@ -10,13 +10,13 @@ export function getReportingPlugin>( config: GatewayConfig, configContext: GatewayConfigContext, ): { - name?: string; + name?: 'Hive' | 'GraphOS'; plugin: GatewayPlugin; } { if (config.reporting?.type === 'hive') { return { name: 'Hive', - plugin: useMeshHive({ + plugin: useHiveConsole({ ...configContext, logger: configContext.logger.child({ reporting: 'Hive' }), ...config.reporting, diff --git a/packages/runtime/src/plugins/useHiveConsole.ts b/packages/runtime/src/plugins/useHiveConsole.ts new file mode 100644 index 000000000..a24aa1660 --- /dev/null +++ b/packages/runtime/src/plugins/useHiveConsole.ts @@ -0,0 +1,24 @@ +import type { HivePluginOptions } from '@graphql-hive/core'; +import { useHive } from '@graphql-hive/yoga'; +import type { Logger } from '@graphql-mesh/types'; +import { GatewayPlugin } from '../types'; + +export type HiveConsolePluginOptions = HivePluginOptions; + +export default function useHiveConsole< + TPluginContext extends Record = Record, + TContext extends Record = Record, +>( + options: HiveConsolePluginOptions & { logger: Logger }, +): GatewayPlugin { + const agent: HiveConsolePluginOptions['agent'] = { + name: 'graphql-hive-gateway', + logger: options.logger, + ...options.agent, + }; + // @ts-expect-error TODO: useHive plugin should inhert the TContext + return useHive({ + ...options, + agent, + }); +} diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index b2fdad4bd..292e83acb 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -14,7 +14,6 @@ import type { MeshFetch, MeshPubSub, OnFetchHook, - YamlConfig, } from '@graphql-mesh/types'; import type { FetchInstrumentation, LogLevel } from '@graphql-mesh/utils'; import type { HTTPExecutorOptions } from '@graphql-tools/executor-http'; @@ -40,6 +39,7 @@ import type { UnifiedGraphConfig } from './handleUnifiedGraphConfig'; import type { UseContentEncodingOpts } from './plugins/useContentEncoding'; import type { AgentFactory } from './plugins/useCustomAgent'; import { DemandControlPluginOptions } from './plugins/useDemandControl'; +import { HiveConsolePluginOptions } from './plugins/useHiveConsole'; import { PropagateHeadersOpts } from './plugins/usePropagateHeaders'; import { UpstreamRetryPluginOptions } from './plugins/useUpstreamRetry'; import { UpstreamTimeoutPluginOptions } from './plugins/useUpstreamTimeout'; @@ -263,7 +263,11 @@ export interface GatewayHiveCDNOptions { } export interface GatewayHiveReportingOptions - extends Omit { + extends Omit< + HiveConsolePluginOptions, + // we omit this property because we define persisted documents in GatewayHivePersistedDocumentsOptions + 'experimental__persistedDocuments' + > { type: 'hive'; /** GraphQL Hive registry access token. */ token: string; diff --git a/yarn.lock b/yarn.lock index 577137790..e32e375b8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3904,22 +3904,7 @@ __metadata: languageName: node linkType: hard -"@graphql-hive/core@npm:0.9.1, @graphql-hive/core@npm:^0.9.0": - version: 0.9.1 - resolution: "@graphql-hive/core@npm:0.9.1" - dependencies: - "@graphql-tools/utils": "npm:^10.0.0" - "@whatwg-node/fetch": "npm:0.10.1" - async-retry: "npm:1.3.3" - lodash.sortby: "npm:4.7.0" - tiny-lru: "npm:8.0.2" - peerDependencies: - graphql: ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - checksum: 10c0/78e22d3c2810197e5e2331ff0fef7dbb7231aa34995f59be27232a735ccc87ccd783b632e6d01d231aed47b381d12ad10a110d5c0443a446fa1917f87e3625ff - languageName: node - linkType: hard - -"@graphql-hive/core@npm:^0.10.0": +"@graphql-hive/core@npm:0.10.0, @graphql-hive/core@npm:^0.10.0": version: 0.10.0 resolution: "@graphql-hive/core@npm:0.10.0" dependencies: @@ -3943,11 +3928,11 @@ __metadata: "@envelop/generic-auth": "npm:^9.0.0" "@graphql-hive/core": "npm:^0.10.0" "@graphql-hive/logger-json": "workspace:^" + "@graphql-hive/yoga": "npm:^0.41.0" "@graphql-mesh/cross-helpers": "npm:^0.4.10" "@graphql-mesh/fusion-composition": "npm:^0.8.0" "@graphql-mesh/fusion-runtime": "workspace:^" "@graphql-mesh/hmac-upstream-signature": "workspace:^" - "@graphql-mesh/plugin-hive": "npm:^0.104.0" "@graphql-mesh/plugin-response-cache": "npm:^0.104.0" "@graphql-mesh/transport-common": "workspace:^" "@graphql-mesh/transport-rest": "npm:^0.9.0" @@ -4149,16 +4134,16 @@ __metadata: languageName: unknown linkType: soft -"@graphql-hive/yoga@npm:^0.40.0": - version: 0.40.1 - resolution: "@graphql-hive/yoga@npm:0.40.1" +"@graphql-hive/yoga@npm:^0.41.0": + version: 0.41.0 + resolution: "@graphql-hive/yoga@npm:0.41.0" dependencies: - "@graphql-hive/core": "npm:0.9.1" + "@graphql-hive/core": "npm:0.10.0" "@graphql-yoga/plugin-persisted-operations": "npm:^3.9.0" peerDependencies: graphql: ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 graphql-yoga: ^5.10.8 - checksum: 10c0/22eb19596aa846aaee494a77bb0ba8ed239194611e111835c0a12ea19504805a551563b1d34dd730007a483e364612baf7b06cf0d53d271c102deeed38c7bb28 + checksum: 10c0/d52e8234bbccdf9fadac028c53a3754bdd427317222cada1f9935b408746cfc84e1726f5def510e82668119bf7a150218e2576f12a062561ed723285faf3b316 languageName: node linkType: hard @@ -4392,23 +4377,6 @@ __metadata: languageName: node linkType: hard -"@graphql-mesh/plugin-hive@npm:^0.104.0": - version: 0.104.1 - resolution: "@graphql-mesh/plugin-hive@npm:0.104.1" - dependencies: - "@graphql-hive/core": "npm:^0.9.0" - "@graphql-hive/yoga": "npm:^0.40.0" - "@graphql-mesh/cross-helpers": "npm:^0.4.10" - "@graphql-mesh/string-interpolation": "npm:^0.5.8" - "@graphql-mesh/types": "npm:^0.104.1" - graphql-yoga: "npm:^5.12.0" - tslib: "npm:^2.4.0" - peerDependencies: - graphql: "*" - checksum: 10c0/c6e6a1c2a14b66a7245ef8b93ae4c90c283f97e3a35c609004641880f1cd5cbbf9aaa8e88698fa17e9ced61952cbfcbd9b511b65feb1051f4f4f7a82def51eae - languageName: node - linkType: hard - "@graphql-mesh/plugin-http-cache@npm:^0.105.0": version: 0.105.1 resolution: "@graphql-mesh/plugin-http-cache@npm:0.105.1" From 76a313c90839ac15072bfa306465b0f6d9cc38a1 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 11:57:38 +0100 Subject: [PATCH 02/14] hive usage reporting target --- packages/runtime/src/getReportingPlugin.ts | 15 +++++++++++++-- packages/runtime/src/types.ts | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/getReportingPlugin.ts b/packages/runtime/src/getReportingPlugin.ts index bda6a53d4..884c24121 100644 --- a/packages/runtime/src/getReportingPlugin.ts +++ b/packages/runtime/src/getReportingPlugin.ts @@ -1,5 +1,7 @@ import { useApolloUsageReport } from '@graphql-yoga/plugin-apollo-usage-report'; -import useHiveConsole from './plugins/useHiveConsole'; +import useHiveConsole, { + HiveConsolePluginOptions, +} from './plugins/useHiveConsole'; import type { GatewayConfig, GatewayConfigContext, @@ -14,12 +16,21 @@ export function getReportingPlugin>( plugin: GatewayPlugin; } { if (config.reporting?.type === 'hive') { + const { target, ...reporting } = config.reporting; + let usage: HiveConsolePluginOptions['usage'] = reporting.usage; + if (usage != null && typeof usage === 'object') { + usage = { + target, + ...usage, + }; + } return { name: 'Hive', plugin: useHiveConsole({ ...configContext, logger: configContext.logger.child({ reporting: 'Hive' }), - ...config.reporting, + ...reporting, + usage, ...(config.persistedDocuments && 'type' in config.persistedDocuments && config.persistedDocuments?.type === 'hive' diff --git a/packages/runtime/src/types.ts b/packages/runtime/src/types.ts index 292e83acb..aa0998ea1 100644 --- a/packages/runtime/src/types.ts +++ b/packages/runtime/src/types.ts @@ -271,6 +271,8 @@ export interface GatewayHiveReportingOptions type: 'hive'; /** GraphQL Hive registry access token. */ token: string; + /** The target to which the usage data should be reported to. */ + target?: string; } export interface GatewayGraphOSOptions { From 9238c6b6e1b6c87d69d8e17662b379e295a60266 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 12:16:32 +0100 Subject: [PATCH 03/14] hive usage in cli --- packages/gateway/src/cli.ts | 26 ++++++- .../src/commands/handleReportingConfig.ts | 78 +++++++++++++++++++ packages/gateway/src/commands/proxy.ts | 26 ++++--- packages/gateway/src/commands/subgraph.ts | 26 ++++--- packages/gateway/src/commands/supergraph.ts | 39 ++++------ 5 files changed, 148 insertions(+), 47 deletions(-) create mode 100644 packages/gateway/src/commands/handleReportingConfig.ts diff --git a/packages/gateway/src/cli.ts b/packages/gateway/src/cli.ts index d0afedde0..dc0f3598e 100644 --- a/packages/gateway/src/cli.ts +++ b/packages/gateway/src/cli.ts @@ -72,9 +72,17 @@ export interface GatewayCLISupergraphConfig } export interface GatewayCLIHiveReportingOptions - extends Omit { + extends Omit { /** - * Hive registry token for usage metrics reporting. + * The target to which the usage data should be reported to. + * + * @default process.env.HIVE_USAGE_TARGET + */ + target?: GatewayHiveReportingOptions['target']; + /** + * Hive registry access token for usage metrics reporting. + * + * @default process.env.HIVE_USAGE_ACCESS_TOKEN || process.env.HIVE_REGISTRY_TOKEN */ token?: GatewayHiveReportingOptions['token']; } @@ -307,9 +315,21 @@ let cli = new Command() .addOption( new Option( '--hive-registry-token ', - 'Hive registry token for usage metrics reporting', + '[DEPRECATED: please use "--hive-usage-target" and "--hive-usage-access-token"] Hive registry token for usage metrics reporting', ).env('HIVE_REGISTRY_TOKEN'), ) + .addOption( + new Option( + '--hive-usage-target ', + 'Hive registry target to which the usage data should be reported to. requires the "--hive-usage-access-token " option', + ).env('HIVE_USAGE_TARGET'), + ) + .addOption( + new Option( + '--hive-usage-access-token ', + 'Hive registry access token for usage metrics reporting. requires the "--hive-usage-target " option', + ).env('HIVE_USAGE_ACCESS_TOKEN'), + ) .option( '--hive-persisted-documents-endpoint ', '[EXPERIMENTAL] Hive CDN endpoint for fetching the persisted documents. requires the "--hive-persisted-documents-token " option', diff --git a/packages/gateway/src/commands/handleReportingConfig.ts b/packages/gateway/src/commands/handleReportingConfig.ts new file mode 100644 index 000000000..5c0f7de1d --- /dev/null +++ b/packages/gateway/src/commands/handleReportingConfig.ts @@ -0,0 +1,78 @@ +import { + CLIContext, + GatewayConfig, + GatewayGraphOSReportingOptions, + GatewayHiveReportingOptions, +} from '..'; + +export function handleReportingConfig( + ctx: CLIContext, + loadedConfig: Partial>>, + opts: { + hiveRegistryToken: string | undefined; + hiveUsageTarget: string | undefined; + hiveUsageAccessToken: string | undefined; + apolloGraphRef: string | undefined; + apolloKey: string | undefined; + }, +): GatewayHiveReportingOptions | GatewayGraphOSReportingOptions | null { + const { + hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, + apolloGraphRef, + apolloKey, + } = opts; + + if (hiveRegistryToken) { + if (hiveUsageAccessToken || hiveUsageTarget) { + ctx.log.error( + `Cannot use "--hive-registry-token" with "--hive-usage-target" or "--hive-usage-access-token". Please use "--hive-usage-target" and "--hive-usage-access-token" instead.`, + ); + process.exit(1); + } + ctx.log.warn( + `"--hive-registry-token" is deprecated! Please use "--hive-usage-target" and "--hive-usage-access-token" instead.`, + ); + ctx.log.info(`Configuring Hive registry reporting`); + return { + ...loadedConfig.reporting, + type: 'hive', + token: hiveRegistryToken, + }; + } else if (hiveUsageAccessToken || hiveUsageTarget) { + if (!hiveUsageAccessToken) { + ctx.log.error( + `Hive usage target needs an access token. Please provide it through the "--hive-usage-access-token " option or the config.`, + ); + process.exit(1); + } + if (!hiveUsageTarget) { + ctx.log.error( + `Hive usage access token needs a target. Please provide it through the "--hive-usage-target " option or the config.`, + ); + process.exit(1); + } + ctx.log.info(`Configuring Hive usage reporting`); + return { + ...loadedConfig.reporting, + type: 'hive', + target: hiveUsageTarget, + token: hiveUsageAccessToken, + }; + } else if (apolloKey) { + ctx.log.info(`Configuring Apollo GraphOS registry reporting`); + if (!apolloGraphRef) { + ctx.log.error( + `Apollo GraphOS requires a graph ref in the format @. Please provide a valid graph ref.`, + ); + process.exit(1); + } + return { + type: 'graphos', + apiKey: apolloKey, + graphRef: apolloGraphRef, + }; + } + return null; +} diff --git a/packages/gateway/src/commands/proxy.ts b/packages/gateway/src/commands/proxy.ts index 2b08adf97..c93c44201 100644 --- a/packages/gateway/src/commands/proxy.ts +++ b/packages/gateway/src/commands/proxy.ts @@ -18,6 +18,7 @@ import { import { startServerForRuntime } from '../servers/startServerForRuntime'; import { handleFork } from './handleFork'; import { handleLoggingConfig } from './handleLoggingOption'; +import { handleReportingConfig } from './handleReportingConfig'; export const addCommand: AddCommand = (ctx, cli) => cli @@ -35,6 +36,8 @@ export const addCommand: AddCommand = (ctx, cli) => hiveCdnEndpoint, hiveCdnKey, hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, maskedErrors, hivePersistedDocumentsEndpoint, hivePersistedDocumentsToken, @@ -95,6 +98,19 @@ export const addCommand: AddCommand = (ctx, cli) => process.exit(1); } + const registryConfig: Pick = {}; + const reporting = handleReportingConfig(ctx, loadedConfig, { + hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, + // proxy can only do reporting to hive registry + apolloGraphRef: undefined, + apolloKey: undefined, + }); + if (reporting) { + registryConfig.reporting = reporting; + } + const pubsub = loadedConfig.pubsub || new PubSub(); const cwd = loadedConfig.cwd || process.cwd(); if (loadedConfig.logging != null) { @@ -128,15 +144,7 @@ export const addCommand: AddCommand = (ctx, cli) => ? loadedConfig.pollingInterval : undefined) || defaultOptions.pollingInterval, - ...(hiveRegistryToken - ? { - reporting: { - ...loadedConfig.reporting, - type: 'hive', - token: hiveRegistryToken, - }, - } - : {}), + ...registryConfig, proxy, schema, logging: ctx.log, diff --git a/packages/gateway/src/commands/subgraph.ts b/packages/gateway/src/commands/subgraph.ts index 08331c7c6..c5a30ea83 100644 --- a/packages/gateway/src/commands/subgraph.ts +++ b/packages/gateway/src/commands/subgraph.ts @@ -22,6 +22,7 @@ import { import { startServerForRuntime } from '../servers/startServerForRuntime'; import { handleFork } from './handleFork'; import { handleLoggingConfig } from './handleLoggingOption'; +import { handleReportingConfig } from './handleReportingConfig'; export const addCommand: AddCommand = (ctx, cli) => cli @@ -37,6 +38,8 @@ export const addCommand: AddCommand = (ctx, cli) => const { maskedErrors, hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, hivePersistedDocumentsEndpoint, hivePersistedDocumentsToken, ...opts @@ -55,6 +58,19 @@ export const addCommand: AddCommand = (ctx, cli) => subgraph = loadedConfig.subgraph!; // TODO: assertion wont be necessary when exactOptionalPropertyTypes } + const registryConfig: Pick = {}; + const reporting = handleReportingConfig(ctx, loadedConfig, { + hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, + // proxy can only do reporting to hive registry + apolloGraphRef: undefined, + apolloKey: undefined, + }); + if (reporting) { + registryConfig.reporting = reporting; + } + const pubsub = loadedConfig.pubsub || new PubSub(); const cwd = loadedConfig.cwd || process.cwd(); if (loadedConfig.logging != null) { @@ -88,15 +104,7 @@ export const addCommand: AddCommand = (ctx, cli) => ? loadedConfig.pollingInterval : undefined) || defaultOptions.pollingInterval, - ...(hiveRegistryToken - ? { - reporting: { - ...loadedConfig.reporting, - type: 'hive', - token: hiveRegistryToken, - }, - } - : {}), + ...registryConfig, subgraph, logging: loadedConfig.logging ?? ctx.log, productName: ctx.productName, diff --git a/packages/gateway/src/commands/supergraph.ts b/packages/gateway/src/commands/supergraph.ts index d5cfa9dd5..c454c0913 100644 --- a/packages/gateway/src/commands/supergraph.ts +++ b/packages/gateway/src/commands/supergraph.ts @@ -28,6 +28,7 @@ import { import { startServerForRuntime } from '../servers/startServerForRuntime'; import { handleFork } from './handleFork'; import { handleLoggingConfig } from './handleLoggingOption'; +import { handleReportingConfig } from './handleReportingConfig'; export const addCommand: AddCommand = (ctx, cli) => cli @@ -50,6 +51,8 @@ export const addCommand: AddCommand = (ctx, cli) => hiveCdnEndpoint, hiveCdnKey, hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, maskedErrors, apolloGraphRef, apolloKey, @@ -151,32 +154,16 @@ export const addCommand: AddCommand = (ctx, cli) => ctx.log.info(`Using default supergraph location: ${supergraph}`); } - let registryConfig: Pick = {}; - - if (hiveRegistryToken) { - ctx.log.info(`Configuring Hive registry reporting`); - registryConfig = { - reporting: { - ...loadedConfig.reporting, - type: 'hive', - token: hiveRegistryToken, - }, - }; - } else if (apolloKey) { - ctx.log.info(`Configuring Apollo GraphOS registry reporting`); - if (!apolloGraphRef) { - ctx.log.error( - `Apollo GraphOS requires a graph ref in the format @. Please provide a valid graph ref.`, - ); - process.exit(1); - } - registryConfig = { - reporting: { - type: 'graphos', - apiKey: apolloKey, - graphRef: apolloGraphRef, - }, - }; + const registryConfig: Pick = {}; + const reporting = handleReportingConfig(ctx, loadedConfig, { + hiveRegistryToken, + hiveUsageTarget, + hiveUsageAccessToken, + apolloGraphRef, + apolloKey, + }); + if (reporting) { + registryConfig.reporting = reporting; } const pubsub = loadedConfig.pubsub || new PubSub(); From 434b01e8a10a0058cc5b486dcd17f2f1a366b362 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 12:17:03 +0100 Subject: [PATCH 04/14] subgraph --- packages/gateway/src/commands/subgraph.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/gateway/src/commands/subgraph.ts b/packages/gateway/src/commands/subgraph.ts index c5a30ea83..0de00ab80 100644 --- a/packages/gateway/src/commands/subgraph.ts +++ b/packages/gateway/src/commands/subgraph.ts @@ -63,7 +63,7 @@ export const addCommand: AddCommand = (ctx, cli) => hiveRegistryToken, hiveUsageTarget, hiveUsageAccessToken, - // proxy can only do reporting to hive registry + // subgraph can only do reporting to hive registry apolloGraphRef: undefined, apolloKey: undefined, }); From 71b444b3782081ff3e37b5ef0e27ced5e0e882b0 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 12:34:07 +0100 Subject: [PATCH 05/14] handle reporting config considers the config --- .../src/commands/handleReportingConfig.ts | 116 ++++++++++-------- 1 file changed, 68 insertions(+), 48 deletions(-) diff --git a/packages/gateway/src/commands/handleReportingConfig.ts b/packages/gateway/src/commands/handleReportingConfig.ts index 5c0f7de1d..14b0ecf23 100644 --- a/packages/gateway/src/commands/handleReportingConfig.ts +++ b/packages/gateway/src/commands/handleReportingConfig.ts @@ -5,64 +5,83 @@ import { GatewayHiveReportingOptions, } from '..'; +export interface ReportingCLIOptions { + hiveRegistryToken: string | undefined; + hiveUsageTarget: string | undefined; + hiveUsageAccessToken: string | undefined; + apolloGraphRef: string | undefined; + apolloKey: string | undefined; +} + export function handleReportingConfig( ctx: CLIContext, loadedConfig: Partial>>, - opts: { - hiveRegistryToken: string | undefined; - hiveUsageTarget: string | undefined; - hiveUsageAccessToken: string | undefined; - apolloGraphRef: string | undefined; - apolloKey: string | undefined; - }, + cliOpts: ReportingCLIOptions, ): GatewayHiveReportingOptions | GatewayGraphOSReportingOptions | null { - const { - hiveRegistryToken, - hiveUsageTarget, - hiveUsageAccessToken, - apolloGraphRef, - apolloKey, - } = opts; + const confOpts: Partial = { + ...(loadedConfig.reporting?.type === 'hive' + ? { + hiveRegistryToken: loadedConfig.reporting.token, + hiveUsageTarget: loadedConfig.reporting.target, + hiveUsageAccessToken: loadedConfig.reporting.token, + } + : {}), + ...(loadedConfig.reporting?.type === 'graphos' + ? { + apolloGraphRef: loadedConfig.reporting.graphRef, + apolloKey: loadedConfig.reporting.apiKey, + } + : {}), + }; + const opts = { ...confOpts, ...cliOpts }; - if (hiveRegistryToken) { - if (hiveUsageAccessToken || hiveUsageTarget) { - ctx.log.error( - `Cannot use "--hive-registry-token" with "--hive-usage-target" or "--hive-usage-access-token". Please use "--hive-usage-target" and "--hive-usage-access-token" instead.`, - ); - process.exit(1); - } - ctx.log.warn( - `"--hive-registry-token" is deprecated! Please use "--hive-usage-target" and "--hive-usage-access-token" instead.`, + if (cliOpts.hiveRegistryToken && cliOpts.hiveUsageAccessToken) { + ctx.log.error( + `Cannot use "--hive-registry-token" with "--hive-usage-access-token". Please use "--hive-usage-target" and "--hive-usage-access-token" or the config instead.`, ); - ctx.log.info(`Configuring Hive registry reporting`); - return { - ...loadedConfig.reporting, - type: 'hive', - token: hiveRegistryToken, - }; - } else if (hiveUsageAccessToken || hiveUsageTarget) { - if (!hiveUsageAccessToken) { - ctx.log.error( - `Hive usage target needs an access token. Please provide it through the "--hive-usage-access-token " option or the config.`, - ); - process.exit(1); - } - if (!hiveUsageTarget) { - ctx.log.error( - `Hive usage access token needs a target. Please provide it through the "--hive-usage-target " option or the config.`, - ); - process.exit(1); + process.exit(1); + } + + if (cliOpts.hiveRegistryToken && opts.hiveUsageTarget) { + ctx.log.error( + `Cannot use "--hive-registry-token" with a target. Please use "--hive-usage-target" and "--hive-usage-access-token" or the config instead.`, + ); + process.exit(1); + } + + if (opts.hiveUsageTarget && !opts.hiveUsageAccessToken) { + ctx.log.error( + `Hive usage target needs an access token. Please provide it through the "--hive-usage-access-token " option or the config.`, + ); + process.exit(1); + } + + if (opts.hiveUsageAccessToken && !opts.hiveUsageTarget) { + ctx.log.error( + `Hive usage access token needs a target. Please provide it through the "--hive-usage-target " option or the config.`, + ); + process.exit(1); + } + + const hiveUsageAccessToken = + opts.hiveUsageAccessToken || opts.hiveRegistryToken; + if (hiveUsageAccessToken) { + // different logs w and w/o the target to disambiguate + if (opts.hiveUsageTarget) { + ctx.log.info(`Configuring Hive usage reporting`); + } else { + ctx.log.info(`Configuring Hive registry reporting`); } - ctx.log.info(`Configuring Hive usage reporting`); return { - ...loadedConfig.reporting, type: 'hive', - target: hiveUsageTarget, token: hiveUsageAccessToken, + target: opts.hiveUsageTarget, }; - } else if (apolloKey) { + } + + if (opts.apolloKey) { ctx.log.info(`Configuring Apollo GraphOS registry reporting`); - if (!apolloGraphRef) { + if (!opts.apolloGraphRef) { ctx.log.error( `Apollo GraphOS requires a graph ref in the format @. Please provide a valid graph ref.`, ); @@ -70,9 +89,10 @@ export function handleReportingConfig( } return { type: 'graphos', - apiKey: apolloKey, - graphRef: apolloGraphRef, + apiKey: opts.apolloKey, + graphRef: opts.apolloGraphRef, }; } + return null; } From 8eea924d144e7e79592fd919fc949cb9ab8823a3 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 13:34:30 +0100 Subject: [PATCH 06/14] pass through reporting --- packages/gateway/src/commands/handleReportingConfig.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/gateway/src/commands/handleReportingConfig.ts b/packages/gateway/src/commands/handleReportingConfig.ts index 14b0ecf23..8e7405ad6 100644 --- a/packages/gateway/src/commands/handleReportingConfig.ts +++ b/packages/gateway/src/commands/handleReportingConfig.ts @@ -73,6 +73,7 @@ export function handleReportingConfig( ctx.log.info(`Configuring Hive registry reporting`); } return { + ...loadedConfig.reporting, type: 'hive', token: hiveUsageAccessToken, target: opts.hiveUsageTarget, @@ -88,6 +89,7 @@ export function handleReportingConfig( process.exit(1); } return { + ...loadedConfig.reporting, type: 'graphos', apiKey: opts.apolloKey, graphRef: opts.apolloGraphRef, From 01a805a9b74c35f06e21c6738e2d756c76067b31 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 13:35:14 +0100 Subject: [PATCH 07/14] no or --- packages/runtime/src/createGatewayRuntime.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/createGatewayRuntime.ts b/packages/runtime/src/createGatewayRuntime.ts index 69bbe3754..a7ae50d03 100644 --- a/packages/runtime/src/createGatewayRuntime.ts +++ b/packages/runtime/src/createGatewayRuntime.ts @@ -191,8 +191,10 @@ export function createGatewayRuntime< let contextBuilder: (context: T) => MaybePromise; let readinessChecker: () => MaybePromise; let getExecutor: (() => MaybePromise) | undefined; - const { name: reportingTarget, plugin: registryPlugin } = - getReportingPlugin(config, configContext) || {}; + const { name: reportingTarget, plugin: registryPlugin } = getReportingPlugin( + config, + configContext, + ); let persistedDocumentsPlugin: GatewayPlugin = {}; if ( config.reporting?.type !== 'hive' && From 4d89a01cf60a693945122d73f334c28f099e032d Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 13:45:49 +0100 Subject: [PATCH 08/14] enable and spread no undefined --- packages/runtime/src/getReportingPlugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/getReportingPlugin.ts b/packages/runtime/src/getReportingPlugin.ts index 884c24121..f8b687a4f 100644 --- a/packages/runtime/src/getReportingPlugin.ts +++ b/packages/runtime/src/getReportingPlugin.ts @@ -27,10 +27,10 @@ export function getReportingPlugin>( return { name: 'Hive', plugin: useHiveConsole({ - ...configContext, logger: configContext.logger.child({ reporting: 'Hive' }), + enabled: true, ...reporting, - usage, + ...(usage ? { usage } : {}), ...(config.persistedDocuments && 'type' in config.persistedDocuments && config.persistedDocuments?.type === 'hive' From 4bbc4b45411e0ee30780c1859d0b08685e544ee3 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 13:58:04 +0100 Subject: [PATCH 09/14] leave disabled --- packages/runtime/src/getReportingPlugin.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/runtime/src/getReportingPlugin.ts b/packages/runtime/src/getReportingPlugin.ts index f8b687a4f..367a3bed8 100644 --- a/packages/runtime/src/getReportingPlugin.ts +++ b/packages/runtime/src/getReportingPlugin.ts @@ -18,10 +18,13 @@ export function getReportingPlugin>( if (config.reporting?.type === 'hive') { const { target, ...reporting } = config.reporting; let usage: HiveConsolePluginOptions['usage'] = reporting.usage; - if (usage != null && typeof usage === 'object') { + if (usage === false) { + // explicitly disabled, leave disabled + } else { + // user specified a target, extend the usage with the given target usage = { target, - ...usage, + ...(typeof usage === 'object' ? { ...usage } : {}), }; } return { From b09cad7616e2d345776902ef63917f4b72bbf873 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 11 Mar 2025 13:00:36 +0000 Subject: [PATCH 10/14] chore(dependencies): updated changesets for modified dependencies --- .../@graphql-hive_gateway-runtime-809-dependencies.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/@graphql-hive_gateway-runtime-809-dependencies.md diff --git a/.changeset/@graphql-hive_gateway-runtime-809-dependencies.md b/.changeset/@graphql-hive_gateway-runtime-809-dependencies.md new file mode 100644 index 000000000..18edcc67e --- /dev/null +++ b/.changeset/@graphql-hive_gateway-runtime-809-dependencies.md @@ -0,0 +1,8 @@ +--- +'@graphql-hive/gateway-runtime': patch +--- + +dependencies updates: + +- Added dependency [`@graphql-hive/yoga@^0.41.0` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.41.0) (to `dependencies`) +- Removed dependency [`@graphql-mesh/plugin-hive@^0.104.0` ↗︎](https://www.npmjs.com/package/@graphql-mesh/plugin-hive/v/0.104.0) (from `dependencies`) From 2e32657b82e39d0bd7ffcd53389faf698a832521 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 14:04:26 +0100 Subject: [PATCH 11/14] changesets --- .changeset/plenty-llamas-push.md | 7 +++++++ .changeset/wet-kiwis-peel.md | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 .changeset/plenty-llamas-push.md create mode 100644 .changeset/wet-kiwis-peel.md diff --git a/.changeset/plenty-llamas-push.md b/.changeset/plenty-llamas-push.md new file mode 100644 index 000000000..e6395c8b6 --- /dev/null +++ b/.changeset/plenty-llamas-push.md @@ -0,0 +1,7 @@ +--- +'@graphql-hive/gateway': patch +--- + +Introduce `target` as a new Hive reporting option + +Deprecate the `--hive-registry-token` CLI option in favour of `--hive-usage-target` and `--hive-usage-access-token` options. \ No newline at end of file diff --git a/.changeset/wet-kiwis-peel.md b/.changeset/wet-kiwis-peel.md new file mode 100644 index 000000000..07d2c784a --- /dev/null +++ b/.changeset/wet-kiwis-peel.md @@ -0,0 +1,5 @@ +--- +'@graphql-hive/gateway-runtime': patch +--- + +Introduce `target` as a new Hive reporting option From 9bf72e06cf3ac06626ef46701196613b2a1fc708 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 14:08:42 +0100 Subject: [PATCH 12/14] minor bigman --- .changeset/plenty-llamas-push.md | 2 +- .changeset/wet-kiwis-peel.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/plenty-llamas-push.md b/.changeset/plenty-llamas-push.md index e6395c8b6..ac6a325ae 100644 --- a/.changeset/plenty-llamas-push.md +++ b/.changeset/plenty-llamas-push.md @@ -1,5 +1,5 @@ --- -'@graphql-hive/gateway': patch +'@graphql-hive/gateway': minor --- Introduce `target` as a new Hive reporting option diff --git a/.changeset/wet-kiwis-peel.md b/.changeset/wet-kiwis-peel.md index 07d2c784a..73c94957a 100644 --- a/.changeset/wet-kiwis-peel.md +++ b/.changeset/wet-kiwis-peel.md @@ -1,5 +1,5 @@ --- -'@graphql-hive/gateway-runtime': patch +'@graphql-hive/gateway-runtime': minor --- Introduce `target` as a new Hive reporting option From bf89e9040a9f46151f6d241dc00376abad7cfa94 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Tue, 11 Mar 2025 14:41:56 +0100 Subject: [PATCH 13/14] use hive console debug mode --- packages/runtime/src/plugins/useHiveConsole.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/runtime/src/plugins/useHiveConsole.ts b/packages/runtime/src/plugins/useHiveConsole.ts index a24aa1660..30902e387 100644 --- a/packages/runtime/src/plugins/useHiveConsole.ts +++ b/packages/runtime/src/plugins/useHiveConsole.ts @@ -1,5 +1,6 @@ import type { HivePluginOptions } from '@graphql-hive/core'; import { useHive } from '@graphql-hive/yoga'; +import { process } from '@graphql-mesh/cross-helpers'; import type { Logger } from '@graphql-mesh/types'; import { GatewayPlugin } from '../types'; @@ -18,6 +19,9 @@ export default function useHiveConsole< }; // @ts-expect-error TODO: useHive plugin should inhert the TContext return useHive({ + debug: ['1', 'y', 'yes', 't', 'true'].includes( + String(process.env['DEBUG']), + ), ...options, agent, }); From 3aa59addc2562eb1e5c602a132ab458aec001ec0 Mon Sep 17 00:00:00 2001 From: Denis Badurina Date: Wed, 12 Mar 2025 17:27:20 +0100 Subject: [PATCH 14/14] changeset --- .changeset/plenty-llamas-push.md | 2 +- .changeset/wet-kiwis-peel.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.changeset/plenty-llamas-push.md b/.changeset/plenty-llamas-push.md index ac6a325ae..a6273f4f9 100644 --- a/.changeset/plenty-llamas-push.md +++ b/.changeset/plenty-llamas-push.md @@ -4,4 +4,4 @@ Introduce `target` as a new Hive reporting option -Deprecate the `--hive-registry-token` CLI option in favour of `--hive-usage-target` and `--hive-usage-access-token` options. \ No newline at end of file +Deprecate the `--hive-registry-token` CLI option in favour of `--hive-usage-target` and `--hive-usage-access-token` options. [Read more on Hive's product update page.](https://the-guild.dev/graphql/hive/product-updates/2025-03-10-new-access-tokens) \ No newline at end of file diff --git a/.changeset/wet-kiwis-peel.md b/.changeset/wet-kiwis-peel.md index 73c94957a..65421aae9 100644 --- a/.changeset/wet-kiwis-peel.md +++ b/.changeset/wet-kiwis-peel.md @@ -3,3 +3,5 @@ --- Introduce `target` as a new Hive reporting option + +[Read more on Hive's product update page.](https://the-guild.dev/graphql/hive/product-updates/2025-03-10-new-access-tokens)