@graphql-hive/gateway-runtime 2.4.0-alpha-886461fbb345099a8fc7f572ceb5fbd67da736cb → 2.4.0-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,38 +1,90 @@
1
1
  # @graphql-hive/gateway-runtime
2
2
 
3
- ## 2.4.0-alpha-886461fbb345099a8fc7f572ceb5fbd67da736cb
3
+ ## 2.4.0-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
4
4
  ### Minor Changes
5
5
 
6
6
 
7
7
 
8
- - [#1636](https://github.com/graphql-hive/gateway/pull/1636) [`ce0d13a`](https://github.com/graphql-hive/gateway/commit/ce0d13a7813a5501fb4c6ba60246f33156298115) Thanks [@EmrysMyrddin](https://github.com/EmrysMyrddin)! - Expose GraphQLError as OpenTelemetry Events.
8
+ - [#1738](https://github.com/graphql-hive/gateway/pull/1738) [`5a2207f`](https://github.com/graphql-hive/gateway/commit/5a2207f13466d56376ae246d4226b6d214b6b3a3) Thanks [@EmrysMyrddin](https://github.com/EmrysMyrddin)! - New Hive CDN mirror and circuit breaker
9
9
 
10
- Errors contains in the result of a graphql operation are now reported as standalone OpenTelemetry
11
- Events (name `graphql.error`) instead of OpenTelemetry Exceptions.
10
+ Hive CDN introduced a new CDN mirror and circuit breaker to mitigate the risk related to Cloudflare
11
+ services failures.
12
12
 
13
- This is aligned with the guidance of the Graphql OpenTelemetry working group.
13
+ You can now provide multiple endpoint in Hive Console related features, and configure the circuit
14
+ breaker handling CDN failure and how it switches to the CDN mirror.
14
15
 
15
- It allows to add more graphql specific attributes to errors reported in a response:
16
+ ### Usage
16
17
 
17
- - `message`: The error message
18
- - `path`: The path in the operation document from which the error originated
19
- - `locations`: The list of related locations in the document source
20
- - `coordinate`: The schema coordinate of the resolver which is the source of the error
18
+ To enable this feature, please provide the mirror endpoint in `supergraph` and `persistedDocument`
19
+ options:
21
20
 
22
- This brings the experimental support of the `coordinate` error attribute in the Yoga Runtime. For
23
- security reason, this attribute is purposefully not serialized, to avoid leaking schema information
24
- to clients.
21
+ ```diff
22
+ import { defineConfig } from '@graphql-hive/gateway'
23
+
24
+ export const gatewayConfig = defineConfig({
25
+ supergraph: {
26
+ type: 'hive',
27
+ - endpoint: 'https://cdn.graphql-hive.com/artifacts/v1/...../supergraph',
28
+ + endpoint: [
29
+ + 'https://cdn.graphql-hive.com/artifacts/v1/...../supergraph',
30
+ + 'https://cdn-mirror.graphql-hive.com/artifacts/v1/...../supergraph'
31
+ + ]
32
+ },
33
+
34
+ persistedDocuments: {
35
+ - endpoint: 'https://cdn.graphql-hive.com/artifacts/v1/...',
36
+ + endpoint: [
37
+ + 'https://cdn.graphql-hive.com/artifacts/v1/...',
38
+ + 'https://cdn-mirror.graphql-hive.com/artifacts/v1/...'
39
+ + ]
40
+ }
41
+ })
42
+ ```
43
+
44
+ ### Configuration
45
+
46
+ The circuit breaker has production ready default configuration, but you customize its behavior:
47
+
48
+ ```ts
49
+ import { defineConfig, CircuitBreakerConfiguration } from '@graphql-hive/gateway';
50
+
51
+ const circuitBreaker: CircuitBreakerConfiguration = {
52
+ resetTimeout: 30_000; // 30s
53
+ errorThresholdPercentage: 50;
54
+ volumeThreshold: 5;
55
+ }
56
+
57
+ export const gatewayConfig = defineConfig({
58
+ supergraph: {
59
+ type: 'hive',
60
+ endpoint: [...],
61
+ circuitBreaker,
62
+ },
63
+
64
+ persistedDocuments: {
65
+ type: 'hive',
66
+ endpoint: [...],
67
+ circuitBreaker,
68
+ },
69
+ });
70
+ ```
25
71
 
26
72
  ### Patch Changes
27
73
 
28
74
 
29
75
 
30
- - [#1636](https://github.com/graphql-hive/gateway/pull/1636) [`7321d7b`](https://github.com/graphql-hive/gateway/commit/7321d7b00b3bfa59ab263346018e630819cc2c3a) Thanks [@EmrysMyrddin](https://github.com/EmrysMyrddin)! - dependencies updates:
76
+ - [#1747](https://github.com/graphql-hive/gateway/pull/1747) [`8fdaef5`](https://github.com/graphql-hive/gateway/commit/8fdaef56d70998dacaed829c278fa7079062ad67) Thanks [@dependabot](https://github.com/apps/dependabot)! - dependencies updates:
31
77
 
32
- - Updated dependency [`graphql-yoga@^5.17.0` ↗︎](https://www.npmjs.com/package/graphql-yoga/v/5.17.0) (from `^5.16.2`, in `dependencies`)
33
- - Updated dependencies [[`7321d7b`](https://github.com/graphql-hive/gateway/commit/7321d7b00b3bfa59ab263346018e630819cc2c3a)]:
34
- - @graphql-mesh/fusion-runtime@1.6.2-alpha-886461fbb345099a8fc7f572ceb5fbd67da736cb
78
+ - Updated dependency [`@graphql-hive/core@^0.18.0` ↗︎](https://www.npmjs.com/package/@graphql-hive/core/v/0.18.0) (from `^0.15.1`, in `dependencies`)
79
+ - Updated dependency [`@graphql-hive/yoga@^0.46.0` ↗︎](https://www.npmjs.com/package/@graphql-hive/yoga/v/0.46.0) (from `^0.43.1`, in `dependencies`)
80
+ - Updated dependencies [[`da8b8e3`](https://github.com/graphql-hive/gateway/commit/da8b8e3f3545487249b11c6577e3889f68527249)]:
81
+ - @graphql-tools/delegate@12.0.2-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
35
82
  - @graphql-mesh/hmac-upstream-signature@2.0.8
83
+ - @graphql-tools/batch-delegate@10.0.8-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
84
+ - @graphql-tools/federation@4.2.6-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
85
+ - @graphql-mesh/fusion-runtime@1.6.2-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
86
+ - @graphql-tools/stitch@10.1.6-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
87
+ - @graphql-tools/wrap@11.1.2-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497
36
88
 
37
89
  ## 2.3.7
38
90
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -143,8 +143,7 @@ const getExecuteFnFromExecutor = utils.memoize1(
143
143
  operationName: args.operationName ?? void 0,
144
144
  rootValue: args.rootValue,
145
145
  context: args.contextValue,
146
- signal: args.signal,
147
- schemaCoordinateInErrors: args.schemaCoordinateInErrors
146
+ signal: args.signal
148
147
  });
149
148
  };
150
149
  }
@@ -578,6 +577,7 @@ function useHiveConsole({
578
577
  }
579
578
  return yoga.useHive({
580
579
  debug: isDebug(),
580
+ logger: options.log,
581
581
  ...options,
582
582
  enabled: !!enabled,
583
583
  token,
@@ -608,6 +608,7 @@ function getReportingPlugin(config, configContext, allowArbitraryDocuments = fal
608
608
  endpoint: config.persistedDocuments.endpoint,
609
609
  accessToken: config.persistedDocuments.token
610
610
  },
611
+ circuitBreaker: config.persistedDocuments.circuitBreaker,
611
612
  // Trick to satisfy the Hive Console plugin types
612
613
  allowArbitraryDocuments
613
614
  }
@@ -2043,6 +2044,7 @@ function createGatewayRuntime(config) {
2043
2044
  endpoint: config.persistedDocuments.endpoint,
2044
2045
  accessToken: config.persistedDocuments.token
2045
2046
  },
2047
+ circuitBreaker: config.persistedDocuments.circuitBreaker,
2046
2048
  // @ts-expect-error - Hive Console plugin options are not compatible yet
2047
2049
  allowArbitraryDocuments: allowArbitraryDocumentsForPersistedDocuments
2048
2050
  }
@@ -2062,7 +2064,7 @@ function createGatewayRuntime(config) {
2062
2064
  clearTimeout(currentTimeout);
2063
2065
  }
2064
2066
  if (pollingInterval) {
2065
- currentTimeout = setTimeout(schemaFetcher, pollingInterval);
2067
+ currentTimeout = setTimeout(schemaFetcher.fetch, pollingInterval);
2066
2068
  }
2067
2069
  }, pausePolling2 = function() {
2068
2070
  if (currentTimeout) {
@@ -2086,81 +2088,99 @@ function createGatewayRuntime(config) {
2086
2088
  let initialFetch$;
2087
2089
  let schemaFetcher;
2088
2090
  if (config.schema && typeof config.schema === "object" && "type" in config.schema) {
2089
- const { endpoint, key } = config.schema;
2090
- const fetcher = core$1.createSchemaFetcher({
2091
- endpoint,
2092
- key,
2093
- logger: logger.LegacyLogger.from(
2094
- configContext.log.child("[hiveSchemaFetcher] ")
2091
+ const { endpoint, key, circuitBreaker } = config.schema;
2092
+ const endpoints = (Array.isArray(endpoint) ? endpoint : [endpoint]).map(
2093
+ (url) => url.endsWith("/sdl") ? url : core$1.joinUrl(
2094
+ url.endsWith("/services") ? url.substring(0, url.length - 8) : url,
2095
+ "sdl"
2095
2096
  )
2097
+ );
2098
+ const fetcher = core$1.createCDNArtifactFetcher({
2099
+ endpoint: endpoints,
2100
+ circuitBreaker,
2101
+ accessKey: key,
2102
+ logger: configContext.log.child("[hiveSchemaFetcher] ")
2096
2103
  });
2097
- schemaFetcher = function fetchSchemaFromCDN() {
2098
- pausePolling2();
2099
- initialFetch$ = promiseHelpers.handleMaybePromise(fetcher, ({ sdl }) => {
2100
- {
2101
- unifiedGraph = graphql.buildSchema(sdl, {
2102
- assumeValid: true,
2103
- assumeValidSDL: true
2104
- });
2105
- }
2106
- continuePolling2();
2107
- return true;
2108
- });
2109
- return initialFetch$;
2104
+ schemaFetcher = {
2105
+ fetch: function fetchSchemaFromCDN() {
2106
+ pausePolling2();
2107
+ initialFetch$ = promiseHelpers.handleMaybePromise(
2108
+ fetcher.fetch,
2109
+ ({ contents }) => {
2110
+ {
2111
+ unifiedGraph = graphql.buildSchema(contents, {
2112
+ assumeValid: true,
2113
+ assumeValidSDL: true
2114
+ });
2115
+ }
2116
+ continuePolling2();
2117
+ return true;
2118
+ }
2119
+ );
2120
+ return initialFetch$;
2121
+ },
2122
+ dispose: () => fetcher.dispose()
2110
2123
  };
2111
2124
  } else if (config.schema) {
2112
2125
  if (!isDynamicUnifiedGraphSchema(config.schema)) {
2113
2126
  delete config.pollingInterval;
2114
2127
  }
2115
- schemaFetcher = function fetchSchema() {
2116
- pausePolling2();
2117
- initialFetch$ = promiseHelpers.handleMaybePromise(
2118
- () => handleUnifiedGraphConfig(
2119
- // @ts-expect-error TODO: what's up with type narrowing
2120
- config.schema,
2121
- configContext
2122
- ),
2123
- (schema) => {
2124
- if (graphql.isSchema(schema)) {
2125
- unifiedGraph = schema;
2126
- } else if (utils.isDocumentNode(schema)) {
2127
- unifiedGraph = graphql.buildASTSchema(schema, {
2128
- assumeValid: true,
2129
- assumeValidSDL: true
2130
- });
2131
- } else {
2132
- unifiedGraph = graphql.buildSchema(schema, {
2133
- noLocation: true,
2134
- assumeValid: true,
2135
- assumeValidSDL: true
2136
- });
2128
+ schemaFetcher = {
2129
+ fetch: function fetchSchema() {
2130
+ pausePolling2();
2131
+ initialFetch$ = promiseHelpers.handleMaybePromise(
2132
+ () => handleUnifiedGraphConfig(
2133
+ // @ts-expect-error TODO: what's up with type narrowing
2134
+ config.schema,
2135
+ configContext
2136
+ ),
2137
+ (schema) => {
2138
+ if (graphql.isSchema(schema)) {
2139
+ unifiedGraph = schema;
2140
+ } else if (utils.isDocumentNode(schema)) {
2141
+ unifiedGraph = graphql.buildASTSchema(schema, {
2142
+ assumeValid: true,
2143
+ assumeValidSDL: true
2144
+ });
2145
+ } else {
2146
+ unifiedGraph = graphql.buildSchema(schema, {
2147
+ noLocation: true,
2148
+ assumeValid: true,
2149
+ assumeValidSDL: true
2150
+ });
2151
+ }
2152
+ continuePolling2();
2153
+ return true;
2137
2154
  }
2138
- continuePolling2();
2139
- return true;
2140
- }
2141
- );
2142
- return initialFetch$;
2155
+ );
2156
+ return initialFetch$;
2157
+ }
2143
2158
  };
2144
2159
  } else {
2145
- schemaFetcher = function fetchSchemaWithExecutor() {
2146
- pausePolling2();
2147
- return promiseHelpers.handleMaybePromise(
2148
- () => wrap.schemaFromExecutor(proxyExecutor, configContext, {
2149
- assumeValid: true
2150
- }),
2151
- (schema) => {
2152
- unifiedGraph = schema;
2153
- continuePolling2();
2154
- return true;
2155
- }
2156
- );
2160
+ schemaFetcher = {
2161
+ fetch: function fetchSchemaWithExecutor() {
2162
+ pausePolling2();
2163
+ return promiseHelpers.handleMaybePromise(
2164
+ () => wrap.schemaFromExecutor(proxyExecutor, configContext, {
2165
+ assumeValid: true
2166
+ }),
2167
+ (schema) => {
2168
+ unifiedGraph = schema;
2169
+ continuePolling2();
2170
+ return true;
2171
+ }
2172
+ );
2173
+ }
2157
2174
  };
2158
2175
  }
2159
- const instrumentedFetcher = schemaFetcher;
2160
- schemaFetcher = (...args) => core.getInstrumented(null).asyncFn(
2161
- instrumentation?.schema,
2162
- instrumentedFetcher
2163
- )(...args);
2176
+ const instrumentedFetcher = schemaFetcher.fetch;
2177
+ schemaFetcher = {
2178
+ ...schemaFetcher,
2179
+ fetch: (...args) => core.getInstrumented(null).asyncFn(
2180
+ instrumentation?.schema,
2181
+ instrumentedFetcher
2182
+ )(...args)
2183
+ };
2164
2184
  getSchema = () => {
2165
2185
  if (unifiedGraph != null) {
2166
2186
  return unifiedGraph;
@@ -2171,21 +2191,21 @@ function createGatewayRuntime(config) {
2171
2191
  () => unifiedGraph
2172
2192
  );
2173
2193
  }
2174
- return promiseHelpers.handleMaybePromise(schemaFetcher, () => unifiedGraph);
2194
+ return promiseHelpers.handleMaybePromise(schemaFetcher.fetch, () => unifiedGraph);
2175
2195
  };
2176
2196
  const shouldSkipValidation = "skipValidation" in config ? config.skipValidation : false;
2177
- const executorPlugin = {
2197
+ unifiedGraphPlugin = {
2178
2198
  onValidate({ params, setResult }) {
2179
2199
  if (shouldSkipValidation || !params.schema) {
2180
2200
  setResult([]);
2181
2201
  }
2182
2202
  },
2183
- onDispose() {
2203
+ async onDispose() {
2184
2204
  pausePolling2();
2185
- return transportExecutorStack.disposeAsync();
2205
+ await transportExecutorStack.disposeAsync();
2206
+ return schemaFetcher.dispose?.();
2186
2207
  }
2187
2208
  };
2188
- unifiedGraphPlugin = executorPlugin;
2189
2209
  readinessChecker = () => promiseHelpers.handleMaybePromise(
2190
2210
  () => proxyExecutor({
2191
2211
  document: graphql.parse(`query ReadinessCheck { __typename }`, {
@@ -2196,7 +2216,7 @@ function createGatewayRuntime(config) {
2196
2216
  );
2197
2217
  schemaInvalidator = () => {
2198
2218
  unifiedGraph = void 0;
2199
- initialFetch$ = schemaFetcher();
2219
+ initialFetch$ = schemaFetcher.fetch();
2200
2220
  };
2201
2221
  } else if ("subgraph" in config) {
2202
2222
  let getSubschemaConfig2 = function() {
@@ -2411,31 +2431,40 @@ function createGatewayRuntime(config) {
2411
2431
  let unifiedGraphFetcher;
2412
2432
  if (typeof config.supergraph === "object" && "type" in config.supergraph) {
2413
2433
  if (config.supergraph.type === "hive") {
2414
- const { endpoint, key } = config.supergraph;
2415
- const fetcher = core$1.createSupergraphSDLFetcher({
2416
- endpoint,
2417
- key,
2418
- logger: logger.LegacyLogger.from(
2419
- configContext.log.child("[hiveSupergraphFetcher] ")
2420
- ),
2434
+ const { endpoint, key, circuitBreaker } = config.supergraph;
2435
+ const endpoints = (Array.isArray(endpoint) ? endpoint : [endpoint]).map(
2436
+ (url) => url.endsWith("/supergraph") ? url : `${url}/supergraph`
2437
+ );
2438
+ const fetcher = core$1.createCDNArtifactFetcher({
2439
+ endpoint: endpoints,
2440
+ accessKey: key,
2441
+ logger: configContext.log.child("[hiveSupergraphFetcher] "),
2421
2442
  // @ts-expect-error - MeshFetch is not compatible with `typeof fetch`
2422
- fetchImplementation: configContext.fetch,
2443
+ fetch: configContext.fetch,
2444
+ circuitBreaker,
2423
2445
  name: "hive-gateway",
2424
2446
  version: globalThis.__VERSION__
2425
2447
  });
2426
- unifiedGraphFetcher = () => fetcher().then(({ supergraphSdl }) => supergraphSdl);
2448
+ unifiedGraphFetcher = {
2449
+ fetch: () => fetcher.fetch().then(({ contents }) => contents),
2450
+ dispose: () => fetcher.dispose()
2451
+ };
2427
2452
  } else if (config.supergraph.type === "graphos") {
2428
2453
  const graphosFetcherContainer = createGraphOSFetcher({
2429
2454
  graphosOpts: config.supergraph,
2430
2455
  configContext,
2431
2456
  pollingInterval: config.pollingInterval
2432
2457
  });
2433
- unifiedGraphFetcher = graphosFetcherContainer.unifiedGraphFetcher;
2458
+ unifiedGraphFetcher = {
2459
+ fetch: graphosFetcherContainer.unifiedGraphFetcher
2460
+ };
2434
2461
  } else {
2435
- unifiedGraphFetcher = () => {
2436
- throw new Error(
2437
- `Unknown supergraph configuration: ${config.supergraph}`
2438
- );
2462
+ unifiedGraphFetcher = {
2463
+ fetch: () => {
2464
+ throw new Error(
2465
+ `Unknown supergraph configuration: ${config.supergraph}`
2466
+ );
2467
+ }
2439
2468
  };
2440
2469
  }
2441
2470
  } else {
@@ -2447,20 +2476,25 @@ function createGatewayRuntime(config) {
2447
2476
  `Polling interval not set for supergraph, if you want to get updates of supergraph, we recommend setting a polling interval`
2448
2477
  );
2449
2478
  }
2450
- unifiedGraphFetcher = () => handleUnifiedGraphConfig(
2451
- // @ts-expect-error TODO: what's up with type narrowing
2452
- config.supergraph,
2453
- configContext
2454
- );
2479
+ unifiedGraphFetcher = {
2480
+ fetch: () => handleUnifiedGraphConfig(
2481
+ // @ts-expect-error TODO: what's up with type narrowing
2482
+ config.supergraph,
2483
+ configContext
2484
+ )
2485
+ };
2455
2486
  }
2456
- const instrumentedGraphFetcher = unifiedGraphFetcher;
2457
- unifiedGraphFetcher = (...args) => core.getInstrumented(null).asyncFn(
2458
- instrumentation?.schema,
2459
- instrumentedGraphFetcher
2460
- )(...args);
2487
+ const instrumentedGraphFetcher = unifiedGraphFetcher.fetch;
2488
+ unifiedGraphFetcher = {
2489
+ ...unifiedGraphFetcher,
2490
+ fetch: (...args) => core.getInstrumented(null).asyncFn(
2491
+ instrumentation?.schema,
2492
+ instrumentedGraphFetcher
2493
+ )(...args)
2494
+ };
2461
2495
  const unifiedGraphManager = new fusionRuntime.UnifiedGraphManager({
2462
2496
  handleUnifiedGraph: config.unifiedGraphHandler,
2463
- getUnifiedGraph: unifiedGraphFetcher,
2497
+ getUnifiedGraph: unifiedGraphFetcher.fetch,
2464
2498
  onUnifiedGraphChange(newUnifiedGraph) {
2465
2499
  unifiedGraph = newUnifiedGraph;
2466
2500
  replaceSchema(newUnifiedGraph);
@@ -2510,7 +2544,9 @@ function createGatewayRuntime(config) {
2510
2544
  getExecutor = () => unifiedGraphManager.getExecutor();
2511
2545
  unifiedGraphPlugin = {
2512
2546
  onDispose() {
2513
- return utils$1.dispose(unifiedGraphManager);
2547
+ return promiseHelpers.unfakePromise(
2548
+ promiseHelpers.fakePromise(void 0).then(() => utils$1.dispose(unifiedGraphManager)).then(() => unifiedGraphFetcher.dispose?.())
2549
+ );
2514
2550
  }
2515
2551
  };
2516
2552
  }
package/dist/index.d.cts CHANGED
@@ -5,6 +5,8 @@ import { Plugin as Plugin$1 } from '@envelop/core';
5
5
  export { withState } from '@envelop/core';
6
6
  import { GenericAuthPluginOptions } from '@envelop/generic-auth';
7
7
  export { ResolveUserFn, ValidateUserFn } from '@envelop/generic-auth';
8
+ import { HivePluginOptions, CircuitBreakerConfiguration } from '@graphql-hive/core';
9
+ export { CircuitBreakerConfiguration } from '@graphql-hive/core';
8
10
  import { Logger, LogLevel } from '@graphql-hive/logger';
9
11
  export * from '@graphql-hive/logger';
10
12
  import { PubSub } from '@graphql-hive/pubsub';
@@ -22,7 +24,6 @@ import { UsePersistedOperationsOptions } from '@graphql-yoga/plugin-persisted-op
22
24
  import { GraphQLResolveInfo } from 'graphql/type';
23
25
  import { Agent } from 'node:http';
24
26
  import { Agent as Agent$1 } from 'node:https';
25
- import { HivePluginOptions } from '@graphql-hive/core';
26
27
  import { FetchAPI } from '@whatwg-node/server';
27
28
  export * from '@whatwg-node/disposablestack';
28
29
  import { Context, ConnectionInitMessage, ServerOptions } from 'graphql-ws';
@@ -414,11 +415,12 @@ interface GatewayHiveCDNOptions {
414
415
  /**
415
416
  * GraphQL Hive CDN endpoint URL.
416
417
  */
417
- endpoint: string;
418
+ endpoint: string | [string, string];
418
419
  /**
419
420
  * GraphQL Hive CDN access key.
420
421
  */
421
422
  key: string;
423
+ circuitBreaker?: CircuitBreakerConfiguration;
422
424
  }
423
425
  interface GatewayHiveReportingOptions extends Omit<HiveConsolePluginOptions, 'experimental__persistedDocuments'> {
424
426
  type: 'hive';
@@ -507,7 +509,11 @@ interface GatewayHivePersistedDocumentsOptions {
507
509
  /**
508
510
  * GraphQL Hive persisted documents CDN endpoint URL.
509
511
  */
510
- endpoint: string;
512
+ endpoint: string | [string, string];
513
+ /**
514
+ * Circuit Breaker configuration to customize CDN failures handling and switch to mirror endpoint.
515
+ */
516
+ circuitBreaker?: CircuitBreakerConfiguration;
511
517
  /**
512
518
  * GraphQL Hive persisted documents CDN access token.
513
519
  */
package/dist/index.d.ts CHANGED
@@ -5,6 +5,8 @@ import { Plugin as Plugin$1 } from '@envelop/core';
5
5
  export { withState } from '@envelop/core';
6
6
  import { GenericAuthPluginOptions } from '@envelop/generic-auth';
7
7
  export { ResolveUserFn, ValidateUserFn } from '@envelop/generic-auth';
8
+ import { HivePluginOptions, CircuitBreakerConfiguration } from '@graphql-hive/core';
9
+ export { CircuitBreakerConfiguration } from '@graphql-hive/core';
8
10
  import { Logger, LogLevel } from '@graphql-hive/logger';
9
11
  export * from '@graphql-hive/logger';
10
12
  import { PubSub } from '@graphql-hive/pubsub';
@@ -22,7 +24,6 @@ import { UsePersistedOperationsOptions } from '@graphql-yoga/plugin-persisted-op
22
24
  import { GraphQLResolveInfo } from 'graphql/type';
23
25
  import { Agent } from 'node:http';
24
26
  import { Agent as Agent$1 } from 'node:https';
25
- import { HivePluginOptions } from '@graphql-hive/core';
26
27
  import { FetchAPI } from '@whatwg-node/server';
27
28
  export * from '@whatwg-node/disposablestack';
28
29
  import { Context, ConnectionInitMessage, ServerOptions } from 'graphql-ws';
@@ -414,11 +415,12 @@ interface GatewayHiveCDNOptions {
414
415
  /**
415
416
  * GraphQL Hive CDN endpoint URL.
416
417
  */
417
- endpoint: string;
418
+ endpoint: string | [string, string];
418
419
  /**
419
420
  * GraphQL Hive CDN access key.
420
421
  */
421
422
  key: string;
423
+ circuitBreaker?: CircuitBreakerConfiguration;
422
424
  }
423
425
  interface GatewayHiveReportingOptions extends Omit<HiveConsolePluginOptions, 'experimental__persistedDocuments'> {
424
426
  type: 'hive';
@@ -507,7 +509,11 @@ interface GatewayHivePersistedDocumentsOptions {
507
509
  /**
508
510
  * GraphQL Hive persisted documents CDN endpoint URL.
509
511
  */
510
- endpoint: string;
512
+ endpoint: string | [string, string];
513
+ /**
514
+ * Circuit Breaker configuration to customize CDN failures handling and switch to mirror endpoint.
515
+ */
516
+ circuitBreaker?: CircuitBreakerConfiguration;
511
517
  /**
512
518
  * GraphQL Hive persisted documents CDN access token.
513
519
  */
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import { isOriginalGraphQLError, getInstrumented as getInstrumented$1 } from '@e
2
2
  export { withState } from '@envelop/core';
3
3
  import { useDisableIntrospection } from '@envelop/disable-introspection';
4
4
  import { useGenericAuth } from '@envelop/generic-auth';
5
- import { createSchemaFetcher, createSupergraphSDLFetcher } from '@graphql-hive/core';
5
+ import { joinUrl, createCDNArtifactFetcher } from '@graphql-hive/core';
6
6
  import { Logger, LegacyLogger } from '@graphql-hive/logger';
7
7
  export * from '@graphql-hive/logger';
8
8
  import { millisecondsToStr, getOnSubgraphExecute, UnifiedGraphManager, restoreExtraDirectives, getTransportEntryMapUsingFusionAndFederationDirectives, getStitchingDirectivesTransformerForSubschema, handleFederationSubschema, handleResolveToDirectives } from '@graphql-mesh/fusion-runtime';
@@ -15,15 +15,15 @@ import { batchDelegateToSchema } from '@graphql-tools/batch-delegate';
15
15
  import { getTypeInfo, EMPTY_OBJECT, delegateToSchema, defaultMergedResolver } from '@graphql-tools/delegate';
16
16
  import { defaultPrintFn as defaultPrintFn$1 } from '@graphql-tools/executor-common';
17
17
  import { getDirectiveExtensions, memoize1, mergeDeep, isValidPath, pathToArray, memoize3, getDirective, createGraphQLError, isAsyncIterable, mapAsyncIterator, createDeferred, isPromise, isDocumentNode, asArray, printSchemaWithDirectives, parseSelectionSet } from '@graphql-tools/utils';
18
- import { wrapSchema, schemaFromExecutor } from '@graphql-tools/wrap';
18
+ import { schemaFromExecutor, wrapSchema } from '@graphql-tools/wrap';
19
19
  import { useCSRFPrevention } from '@graphql-yoga/plugin-csrf-prevention';
20
20
  import { useDeferStream } from '@graphql-yoga/plugin-defer-stream';
21
21
  import { usePersistedOperations } from '@graphql-yoga/plugin-persisted-operations';
22
22
  import { AsyncDisposableStack } from '@whatwg-node/disposablestack';
23
23
  export * from '@whatwg-node/disposablestack';
24
- import { handleMaybePromise, iterateAsync } from '@whatwg-node/promise-helpers';
24
+ import { handleMaybePromise, iterateAsync, unfakePromise, fakePromise } from '@whatwg-node/promise-helpers';
25
25
  import { useCookies } from '@whatwg-node/server-plugin-cookies';
26
- import { print, visit, visitWithTypeInfo, getArgumentValues, getNamedType, isIntrospectionType, isListType, isCompositeType, getOperationAST, isSchema, parse, buildASTSchema, buildSchema } from 'graphql';
26
+ import { print, visit, visitWithTypeInfo, getArgumentValues, getNamedType, isIntrospectionType, isListType, isCompositeType, getOperationAST, isSchema, parse, buildSchema, buildASTSchema } from 'graphql';
27
27
  import { isAsyncIterable as isAsyncIterable$1, useReadinessCheck, useExecutionCancellation, createYoga, chain, mergeSchemas } from 'graphql-yoga';
28
28
  import { DEFAULT_UPLINKS, fetchSupergraphSdlFromManagedFederation } from '@graphql-tools/federation';
29
29
  import { useApolloUsageReport } from '@graphql-yoga/plugin-apollo-usage-report';
@@ -142,8 +142,7 @@ const getExecuteFnFromExecutor = memoize1(
142
142
  operationName: args.operationName ?? void 0,
143
143
  rootValue: args.rootValue,
144
144
  context: args.contextValue,
145
- signal: args.signal,
146
- schemaCoordinateInErrors: args.schemaCoordinateInErrors
145
+ signal: args.signal
147
146
  });
148
147
  };
149
148
  }
@@ -577,6 +576,7 @@ function useHiveConsole({
577
576
  }
578
577
  return useHive({
579
578
  debug: isDebug(),
579
+ logger: options.log,
580
580
  ...options,
581
581
  enabled: !!enabled,
582
582
  token,
@@ -607,6 +607,7 @@ function getReportingPlugin(config, configContext, allowArbitraryDocuments = fal
607
607
  endpoint: config.persistedDocuments.endpoint,
608
608
  accessToken: config.persistedDocuments.token
609
609
  },
610
+ circuitBreaker: config.persistedDocuments.circuitBreaker,
610
611
  // Trick to satisfy the Hive Console plugin types
611
612
  allowArbitraryDocuments
612
613
  }
@@ -2042,6 +2043,7 @@ function createGatewayRuntime(config) {
2042
2043
  endpoint: config.persistedDocuments.endpoint,
2043
2044
  accessToken: config.persistedDocuments.token
2044
2045
  },
2046
+ circuitBreaker: config.persistedDocuments.circuitBreaker,
2045
2047
  // @ts-expect-error - Hive Console plugin options are not compatible yet
2046
2048
  allowArbitraryDocuments: allowArbitraryDocumentsForPersistedDocuments
2047
2049
  }
@@ -2061,7 +2063,7 @@ function createGatewayRuntime(config) {
2061
2063
  clearTimeout(currentTimeout);
2062
2064
  }
2063
2065
  if (pollingInterval) {
2064
- currentTimeout = setTimeout(schemaFetcher, pollingInterval);
2066
+ currentTimeout = setTimeout(schemaFetcher.fetch, pollingInterval);
2065
2067
  }
2066
2068
  }, pausePolling2 = function() {
2067
2069
  if (currentTimeout) {
@@ -2085,81 +2087,99 @@ function createGatewayRuntime(config) {
2085
2087
  let initialFetch$;
2086
2088
  let schemaFetcher;
2087
2089
  if (config.schema && typeof config.schema === "object" && "type" in config.schema) {
2088
- const { endpoint, key } = config.schema;
2089
- const fetcher = createSchemaFetcher({
2090
- endpoint,
2091
- key,
2092
- logger: LegacyLogger.from(
2093
- configContext.log.child("[hiveSchemaFetcher] ")
2090
+ const { endpoint, key, circuitBreaker } = config.schema;
2091
+ const endpoints = (Array.isArray(endpoint) ? endpoint : [endpoint]).map(
2092
+ (url) => url.endsWith("/sdl") ? url : joinUrl(
2093
+ url.endsWith("/services") ? url.substring(0, url.length - 8) : url,
2094
+ "sdl"
2094
2095
  )
2096
+ );
2097
+ const fetcher = createCDNArtifactFetcher({
2098
+ endpoint: endpoints,
2099
+ circuitBreaker,
2100
+ accessKey: key,
2101
+ logger: configContext.log.child("[hiveSchemaFetcher] ")
2095
2102
  });
2096
- schemaFetcher = function fetchSchemaFromCDN() {
2097
- pausePolling2();
2098
- initialFetch$ = handleMaybePromise(fetcher, ({ sdl }) => {
2099
- {
2100
- unifiedGraph = buildSchema(sdl, {
2101
- assumeValid: true,
2102
- assumeValidSDL: true
2103
- });
2104
- }
2105
- continuePolling2();
2106
- return true;
2107
- });
2108
- return initialFetch$;
2103
+ schemaFetcher = {
2104
+ fetch: function fetchSchemaFromCDN() {
2105
+ pausePolling2();
2106
+ initialFetch$ = handleMaybePromise(
2107
+ fetcher.fetch,
2108
+ ({ contents }) => {
2109
+ {
2110
+ unifiedGraph = buildSchema(contents, {
2111
+ assumeValid: true,
2112
+ assumeValidSDL: true
2113
+ });
2114
+ }
2115
+ continuePolling2();
2116
+ return true;
2117
+ }
2118
+ );
2119
+ return initialFetch$;
2120
+ },
2121
+ dispose: () => fetcher.dispose()
2109
2122
  };
2110
2123
  } else if (config.schema) {
2111
2124
  if (!isDynamicUnifiedGraphSchema(config.schema)) {
2112
2125
  delete config.pollingInterval;
2113
2126
  }
2114
- schemaFetcher = function fetchSchema() {
2115
- pausePolling2();
2116
- initialFetch$ = handleMaybePromise(
2117
- () => handleUnifiedGraphConfig(
2118
- // @ts-expect-error TODO: what's up with type narrowing
2119
- config.schema,
2120
- configContext
2121
- ),
2122
- (schema) => {
2123
- if (isSchema(schema)) {
2124
- unifiedGraph = schema;
2125
- } else if (isDocumentNode(schema)) {
2126
- unifiedGraph = buildASTSchema(schema, {
2127
- assumeValid: true,
2128
- assumeValidSDL: true
2129
- });
2130
- } else {
2131
- unifiedGraph = buildSchema(schema, {
2132
- noLocation: true,
2133
- assumeValid: true,
2134
- assumeValidSDL: true
2135
- });
2127
+ schemaFetcher = {
2128
+ fetch: function fetchSchema() {
2129
+ pausePolling2();
2130
+ initialFetch$ = handleMaybePromise(
2131
+ () => handleUnifiedGraphConfig(
2132
+ // @ts-expect-error TODO: what's up with type narrowing
2133
+ config.schema,
2134
+ configContext
2135
+ ),
2136
+ (schema) => {
2137
+ if (isSchema(schema)) {
2138
+ unifiedGraph = schema;
2139
+ } else if (isDocumentNode(schema)) {
2140
+ unifiedGraph = buildASTSchema(schema, {
2141
+ assumeValid: true,
2142
+ assumeValidSDL: true
2143
+ });
2144
+ } else {
2145
+ unifiedGraph = buildSchema(schema, {
2146
+ noLocation: true,
2147
+ assumeValid: true,
2148
+ assumeValidSDL: true
2149
+ });
2150
+ }
2151
+ continuePolling2();
2152
+ return true;
2136
2153
  }
2137
- continuePolling2();
2138
- return true;
2139
- }
2140
- );
2141
- return initialFetch$;
2154
+ );
2155
+ return initialFetch$;
2156
+ }
2142
2157
  };
2143
2158
  } else {
2144
- schemaFetcher = function fetchSchemaWithExecutor() {
2145
- pausePolling2();
2146
- return handleMaybePromise(
2147
- () => schemaFromExecutor(proxyExecutor, configContext, {
2148
- assumeValid: true
2149
- }),
2150
- (schema) => {
2151
- unifiedGraph = schema;
2152
- continuePolling2();
2153
- return true;
2154
- }
2155
- );
2159
+ schemaFetcher = {
2160
+ fetch: function fetchSchemaWithExecutor() {
2161
+ pausePolling2();
2162
+ return handleMaybePromise(
2163
+ () => schemaFromExecutor(proxyExecutor, configContext, {
2164
+ assumeValid: true
2165
+ }),
2166
+ (schema) => {
2167
+ unifiedGraph = schema;
2168
+ continuePolling2();
2169
+ return true;
2170
+ }
2171
+ );
2172
+ }
2156
2173
  };
2157
2174
  }
2158
- const instrumentedFetcher = schemaFetcher;
2159
- schemaFetcher = (...args) => getInstrumented$1(null).asyncFn(
2160
- instrumentation?.schema,
2161
- instrumentedFetcher
2162
- )(...args);
2175
+ const instrumentedFetcher = schemaFetcher.fetch;
2176
+ schemaFetcher = {
2177
+ ...schemaFetcher,
2178
+ fetch: (...args) => getInstrumented$1(null).asyncFn(
2179
+ instrumentation?.schema,
2180
+ instrumentedFetcher
2181
+ )(...args)
2182
+ };
2163
2183
  getSchema = () => {
2164
2184
  if (unifiedGraph != null) {
2165
2185
  return unifiedGraph;
@@ -2170,21 +2190,21 @@ function createGatewayRuntime(config) {
2170
2190
  () => unifiedGraph
2171
2191
  );
2172
2192
  }
2173
- return handleMaybePromise(schemaFetcher, () => unifiedGraph);
2193
+ return handleMaybePromise(schemaFetcher.fetch, () => unifiedGraph);
2174
2194
  };
2175
2195
  const shouldSkipValidation = "skipValidation" in config ? config.skipValidation : false;
2176
- const executorPlugin = {
2196
+ unifiedGraphPlugin = {
2177
2197
  onValidate({ params, setResult }) {
2178
2198
  if (shouldSkipValidation || !params.schema) {
2179
2199
  setResult([]);
2180
2200
  }
2181
2201
  },
2182
- onDispose() {
2202
+ async onDispose() {
2183
2203
  pausePolling2();
2184
- return transportExecutorStack.disposeAsync();
2204
+ await transportExecutorStack.disposeAsync();
2205
+ return schemaFetcher.dispose?.();
2185
2206
  }
2186
2207
  };
2187
- unifiedGraphPlugin = executorPlugin;
2188
2208
  readinessChecker = () => handleMaybePromise(
2189
2209
  () => proxyExecutor({
2190
2210
  document: parse(`query ReadinessCheck { __typename }`, {
@@ -2195,7 +2215,7 @@ function createGatewayRuntime(config) {
2195
2215
  );
2196
2216
  schemaInvalidator = () => {
2197
2217
  unifiedGraph = void 0;
2198
- initialFetch$ = schemaFetcher();
2218
+ initialFetch$ = schemaFetcher.fetch();
2199
2219
  };
2200
2220
  } else if ("subgraph" in config) {
2201
2221
  let getSubschemaConfig2 = function() {
@@ -2410,31 +2430,40 @@ function createGatewayRuntime(config) {
2410
2430
  let unifiedGraphFetcher;
2411
2431
  if (typeof config.supergraph === "object" && "type" in config.supergraph) {
2412
2432
  if (config.supergraph.type === "hive") {
2413
- const { endpoint, key } = config.supergraph;
2414
- const fetcher = createSupergraphSDLFetcher({
2415
- endpoint,
2416
- key,
2417
- logger: LegacyLogger.from(
2418
- configContext.log.child("[hiveSupergraphFetcher] ")
2419
- ),
2433
+ const { endpoint, key, circuitBreaker } = config.supergraph;
2434
+ const endpoints = (Array.isArray(endpoint) ? endpoint : [endpoint]).map(
2435
+ (url) => url.endsWith("/supergraph") ? url : `${url}/supergraph`
2436
+ );
2437
+ const fetcher = createCDNArtifactFetcher({
2438
+ endpoint: endpoints,
2439
+ accessKey: key,
2440
+ logger: configContext.log.child("[hiveSupergraphFetcher] "),
2420
2441
  // @ts-expect-error - MeshFetch is not compatible with `typeof fetch`
2421
- fetchImplementation: configContext.fetch,
2442
+ fetch: configContext.fetch,
2443
+ circuitBreaker,
2422
2444
  name: "hive-gateway",
2423
2445
  version: globalThis.__VERSION__
2424
2446
  });
2425
- unifiedGraphFetcher = () => fetcher().then(({ supergraphSdl }) => supergraphSdl);
2447
+ unifiedGraphFetcher = {
2448
+ fetch: () => fetcher.fetch().then(({ contents }) => contents),
2449
+ dispose: () => fetcher.dispose()
2450
+ };
2426
2451
  } else if (config.supergraph.type === "graphos") {
2427
2452
  const graphosFetcherContainer = createGraphOSFetcher({
2428
2453
  graphosOpts: config.supergraph,
2429
2454
  configContext,
2430
2455
  pollingInterval: config.pollingInterval
2431
2456
  });
2432
- unifiedGraphFetcher = graphosFetcherContainer.unifiedGraphFetcher;
2457
+ unifiedGraphFetcher = {
2458
+ fetch: graphosFetcherContainer.unifiedGraphFetcher
2459
+ };
2433
2460
  } else {
2434
- unifiedGraphFetcher = () => {
2435
- throw new Error(
2436
- `Unknown supergraph configuration: ${config.supergraph}`
2437
- );
2461
+ unifiedGraphFetcher = {
2462
+ fetch: () => {
2463
+ throw new Error(
2464
+ `Unknown supergraph configuration: ${config.supergraph}`
2465
+ );
2466
+ }
2438
2467
  };
2439
2468
  }
2440
2469
  } else {
@@ -2446,20 +2475,25 @@ function createGatewayRuntime(config) {
2446
2475
  `Polling interval not set for supergraph, if you want to get updates of supergraph, we recommend setting a polling interval`
2447
2476
  );
2448
2477
  }
2449
- unifiedGraphFetcher = () => handleUnifiedGraphConfig(
2450
- // @ts-expect-error TODO: what's up with type narrowing
2451
- config.supergraph,
2452
- configContext
2453
- );
2478
+ unifiedGraphFetcher = {
2479
+ fetch: () => handleUnifiedGraphConfig(
2480
+ // @ts-expect-error TODO: what's up with type narrowing
2481
+ config.supergraph,
2482
+ configContext
2483
+ )
2484
+ };
2454
2485
  }
2455
- const instrumentedGraphFetcher = unifiedGraphFetcher;
2456
- unifiedGraphFetcher = (...args) => getInstrumented$1(null).asyncFn(
2457
- instrumentation?.schema,
2458
- instrumentedGraphFetcher
2459
- )(...args);
2486
+ const instrumentedGraphFetcher = unifiedGraphFetcher.fetch;
2487
+ unifiedGraphFetcher = {
2488
+ ...unifiedGraphFetcher,
2489
+ fetch: (...args) => getInstrumented$1(null).asyncFn(
2490
+ instrumentation?.schema,
2491
+ instrumentedGraphFetcher
2492
+ )(...args)
2493
+ };
2460
2494
  const unifiedGraphManager = new UnifiedGraphManager({
2461
2495
  handleUnifiedGraph: config.unifiedGraphHandler,
2462
- getUnifiedGraph: unifiedGraphFetcher,
2496
+ getUnifiedGraph: unifiedGraphFetcher.fetch,
2463
2497
  onUnifiedGraphChange(newUnifiedGraph) {
2464
2498
  unifiedGraph = newUnifiedGraph;
2465
2499
  replaceSchema(newUnifiedGraph);
@@ -2509,7 +2543,9 @@ function createGatewayRuntime(config) {
2509
2543
  getExecutor = () => unifiedGraphManager.getExecutor();
2510
2544
  unifiedGraphPlugin = {
2511
2545
  onDispose() {
2512
- return dispose(unifiedGraphManager);
2546
+ return unfakePromise(
2547
+ fakePromise(void 0).then(() => dispose(unifiedGraphManager)).then(() => unifiedGraphFetcher.dispose?.())
2548
+ );
2513
2549
  }
2514
2550
  };
2515
2551
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphql-hive/gateway-runtime",
3
- "version": "2.4.0-alpha-886461fbb345099a8fc7f572ceb5fbd67da736cb",
3
+ "version": "2.4.0-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,26 +49,26 @@
49
49
  "@envelop/disable-introspection": "^9.0.0",
50
50
  "@envelop/generic-auth": "^11.0.0",
51
51
  "@envelop/instrumentation": "^1.0.0",
52
- "@graphql-hive/core": "^0.15.1",
52
+ "@graphql-hive/core": "^0.18.0",
53
53
  "@graphql-hive/logger": "^1.0.9",
54
54
  "@graphql-hive/pubsub": "^2.1.1",
55
55
  "@graphql-hive/signal": "^2.0.0",
56
- "@graphql-hive/yoga": "^0.43.1",
56
+ "@graphql-hive/yoga": "^0.46.0",
57
57
  "@graphql-mesh/cross-helpers": "^0.4.10",
58
- "@graphql-mesh/fusion-runtime": "1.6.2-alpha-886461fbb345099a8fc7f572ceb5fbd67da736cb",
58
+ "@graphql-mesh/fusion-runtime": "1.6.2-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
59
59
  "@graphql-mesh/hmac-upstream-signature": "^2.0.8",
60
60
  "@graphql-mesh/plugin-response-cache": "^0.104.18",
61
61
  "@graphql-mesh/transport-common": "^1.0.12",
62
62
  "@graphql-mesh/types": "^0.104.16",
63
63
  "@graphql-mesh/utils": "^0.104.16",
64
- "@graphql-tools/batch-delegate": "^10.0.7",
65
- "@graphql-tools/delegate": "^12.0.1",
64
+ "@graphql-tools/batch-delegate": "10.0.8-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
65
+ "@graphql-tools/delegate": "12.0.2-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
66
66
  "@graphql-tools/executor-common": "^1.0.5",
67
67
  "@graphql-tools/executor-http": "^3.0.7",
68
- "@graphql-tools/federation": "^4.2.5",
69
- "@graphql-tools/stitch": "^10.1.5",
68
+ "@graphql-tools/federation": "4.2.6-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
69
+ "@graphql-tools/stitch": "10.1.6-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
70
70
  "@graphql-tools/utils": "^10.10.3",
71
- "@graphql-tools/wrap": "^11.1.1",
71
+ "@graphql-tools/wrap": "11.1.2-alpha-65ad5f97b6cf2a8dd5ad0a7bb8ea9cf3b540b497",
72
72
  "@graphql-yoga/plugin-apollo-usage-report": "^0.12.0",
73
73
  "@graphql-yoga/plugin-csrf-prevention": "^3.16.2",
74
74
  "@graphql-yoga/plugin-defer-stream": "^3.16.2",
@@ -79,7 +79,7 @@
79
79
  "@whatwg-node/server": "^0.10.17",
80
80
  "@whatwg-node/server-plugin-cookies": "^1.0.5",
81
81
  "graphql-ws": "^6.0.6",
82
- "graphql-yoga": "^5.17.0",
82
+ "graphql-yoga": "^5.16.2",
83
83
  "tslib": "^2.8.1"
84
84
  },
85
85
  "devDependencies": {
@@ -98,7 +98,7 @@
98
98
  "pkgroll": "2.21.4",
99
99
  "react": "^19.2.0",
100
100
  "react-dom": "^19.2.0",
101
- "tsx": "4.20.6"
101
+ "tsx": "4.21.0"
102
102
  },
103
103
  "sideEffects": false
104
104
  }