@graphql-hive/router-runtime 1.1.0-rc-924ffb15d84292a020a45655046fd359ea9f02d5 → 1.1.0-rc-aa2a330ec509cf750e8722741cb18aed3ad01793
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 +12 -3
- package/dist/index.cjs +78 -42
- package/dist/index.d.cts +259 -2
- package/dist/index.d.ts +259 -2
- package/dist/index.js +78 -43
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @graphql-hive/router-runtime
|
|
2
2
|
|
|
3
|
-
## 1.1.0-rc-
|
|
3
|
+
## 1.1.0-rc-aa2a330ec509cf750e8722741cb18aed3ad01793
|
|
4
4
|
### Minor Changes
|
|
5
5
|
|
|
6
6
|
|
|
@@ -17,6 +17,11 @@
|
|
|
17
17
|
- Updated dependency [`@graphql-hive/router-query-planner@^0.0.4` ↗︎](https://www.npmjs.com/package/@graphql-hive/router-query-planner/v/0.0.4) (from `^0.0.3`, in `dependencies`)
|
|
18
18
|
|
|
19
19
|
|
|
20
|
+
- [#1739](https://github.com/graphql-hive/gateway/pull/1739) [`8ff2e47`](https://github.com/graphql-hive/gateway/commit/8ff2e471f368d5e41f91a7fe1f1b0e494ef3e6ff) Thanks [@enisdenjo](https://github.com/enisdenjo)! - dependencies updates:
|
|
21
|
+
|
|
22
|
+
- Updated dependency [`@graphql-hive/router-query-planner@^0.0.6` ↗︎](https://www.npmjs.com/package/@graphql-hive/router-query-planner/v/0.0.6) (from `^0.0.4`, in `dependencies`)
|
|
23
|
+
|
|
24
|
+
|
|
20
25
|
- [#1740](https://github.com/graphql-hive/gateway/pull/1740) [`9cfe2a5`](https://github.com/graphql-hive/gateway/commit/9cfe2a555fcbc9a70ba04b32d6844a7a795de624) Thanks [@dependabot](https://github.com/apps/dependabot)! - dependencies updates:
|
|
21
26
|
|
|
22
27
|
- Updated dependency [`@graphql-hive/router-query-planner@^0.0.6` ↗︎](https://www.npmjs.com/package/@graphql-hive/router-query-planner/v/0.0.6) (from `^0.0.4`, in `dependencies`)
|
|
@@ -24,9 +29,13 @@
|
|
|
24
29
|
|
|
25
30
|
- [#1708](https://github.com/graphql-hive/gateway/pull/1708) [`bc6cddd`](https://github.com/graphql-hive/gateway/commit/bc6cddd1c53a012dd02a1d8a7217a28e65cc6ae9) Thanks [@ardatan](https://github.com/ardatan)! - Handle listed enum values correctly
|
|
26
31
|
Previously when a field like `[MyEnum!]!` is projected, it was projecting it like it is `MyEnum`.
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
- [#1739](https://github.com/graphql-hive/gateway/pull/1739) [`8ff2e47`](https://github.com/graphql-hive/gateway/commit/8ff2e471f368d5e41f91a7fe1f1b0e494ef3e6ff) Thanks [@enisdenjo](https://github.com/enisdenjo)! - Expose the query plan by using the `useQueryPlan` plugin
|
|
35
|
+
|
|
27
36
|
- Updated dependencies [[`bc6cddd`](https://github.com/graphql-hive/gateway/commit/bc6cddd1c53a012dd02a1d8a7217a28e65cc6ae9)]:
|
|
28
|
-
- @graphql-mesh/fusion-runtime@1.6.0-rc-
|
|
29
|
-
- @graphql-tools/federation@4.2.4-rc-
|
|
37
|
+
- @graphql-mesh/fusion-runtime@1.6.0-rc-aa2a330ec509cf750e8722741cb18aed3ad01793
|
|
38
|
+
- @graphql-tools/federation@4.2.4-rc-aa2a330ec509cf750e8722741cb18aed3ad01793
|
|
30
39
|
|
|
31
40
|
## 1.0.1
|
|
32
41
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -1071,6 +1071,7 @@ function projectRequires(requiresSelections, entity, supergraphSchema) {
|
|
|
1071
1071
|
return result;
|
|
1072
1072
|
}
|
|
1073
1073
|
|
|
1074
|
+
const queryPlanForExecutionRequestContext = /* @__PURE__ */ new WeakMap();
|
|
1074
1075
|
function getLazyValue(factory) {
|
|
1075
1076
|
let _value;
|
|
1076
1077
|
return function() {
|
|
@@ -1141,52 +1142,59 @@ function unifiedGraphHandler(opts) {
|
|
|
1141
1142
|
executionRequest.document,
|
|
1142
1143
|
executionRequest.operationName || null
|
|
1143
1144
|
),
|
|
1144
|
-
(queryPlan) =>
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1145
|
+
(queryPlan) => {
|
|
1146
|
+
queryPlanForExecutionRequestContext.set(
|
|
1147
|
+
// setter like getter
|
|
1148
|
+
executionRequest.context || executionRequest.document,
|
|
1149
|
+
queryPlan
|
|
1150
|
+
);
|
|
1151
|
+
return executeQueryPlan({
|
|
1152
|
+
supergraphSchema,
|
|
1153
|
+
executionRequest,
|
|
1154
|
+
onSubgraphExecute(subgraphName, executionRequest2) {
|
|
1155
|
+
const subschema = getSubschema(subgraphName);
|
|
1156
|
+
if (subschema.transforms?.length) {
|
|
1157
|
+
const transforms = subschema.transforms;
|
|
1158
|
+
const transformationContext = /* @__PURE__ */ Object.create(null);
|
|
1159
|
+
for (const transform of transforms) {
|
|
1160
|
+
if (transform.transformRequest) {
|
|
1161
|
+
executionRequest2 = transform.transformRequest(
|
|
1162
|
+
executionRequest2,
|
|
1163
|
+
void 0,
|
|
1164
|
+
transformationContext
|
|
1165
|
+
);
|
|
1166
|
+
}
|
|
1159
1167
|
}
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1168
|
+
return promiseHelpers.handleMaybePromise(
|
|
1169
|
+
() => opts.onSubgraphExecute(subgraphName, executionRequest2),
|
|
1170
|
+
(executionResult) => {
|
|
1171
|
+
function handleResult(executionResult2) {
|
|
1172
|
+
for (const transform of transforms.toReversed()) {
|
|
1173
|
+
if (transform.transformResult) {
|
|
1174
|
+
executionResult2 = transform.transformResult(
|
|
1175
|
+
executionResult2,
|
|
1176
|
+
void 0,
|
|
1177
|
+
transformationContext
|
|
1178
|
+
);
|
|
1179
|
+
}
|
|
1172
1180
|
}
|
|
1181
|
+
return executionResult2;
|
|
1173
1182
|
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
);
|
|
1183
|
+
if (utils.isAsyncIterable(executionResult)) {
|
|
1184
|
+
return promiseHelpers.mapAsyncIterator(
|
|
1185
|
+
executionResult,
|
|
1186
|
+
(result) => handleResult(result)
|
|
1187
|
+
);
|
|
1188
|
+
}
|
|
1189
|
+
return handleResult(executionResult);
|
|
1181
1190
|
}
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
);
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
})
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
return opts.onSubgraphExecute(subgraphName, executionRequest2);
|
|
1194
|
+
},
|
|
1195
|
+
queryPlan
|
|
1196
|
+
});
|
|
1197
|
+
}
|
|
1190
1198
|
);
|
|
1191
1199
|
}
|
|
1192
1200
|
};
|
|
@@ -1215,4 +1223,32 @@ function isIntrospection(document) {
|
|
|
1215
1223
|
return containsIntrospectionField || onlyQueryTypenameFields;
|
|
1216
1224
|
}
|
|
1217
1225
|
|
|
1226
|
+
function useQueryPlan(opts = {}) {
|
|
1227
|
+
const { expose, onQueryPlan } = opts;
|
|
1228
|
+
return {
|
|
1229
|
+
onExecute({ context, args }) {
|
|
1230
|
+
return {
|
|
1231
|
+
onExecuteDone({ result, setResult }) {
|
|
1232
|
+
const queryPlan = queryPlanForExecutionRequestContext.get(
|
|
1233
|
+
// getter like setter
|
|
1234
|
+
context || args.document
|
|
1235
|
+
);
|
|
1236
|
+
onQueryPlan?.(queryPlan);
|
|
1237
|
+
const shouldExpose = typeof expose === "function" ? expose(context.request) : expose;
|
|
1238
|
+
if (shouldExpose && !utils.isAsyncIterable(result)) {
|
|
1239
|
+
setResult({
|
|
1240
|
+
...result,
|
|
1241
|
+
extensions: {
|
|
1242
|
+
...result.extensions,
|
|
1243
|
+
queryPlan
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1218
1253
|
exports.unifiedGraphHandler = unifiedGraphHandler;
|
|
1254
|
+
exports.useQueryPlan = useQueryPlan;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,262 @@
|
|
|
1
|
-
import { UnifiedGraphHandlerOpts, UnifiedGraphHandlerResult } from '@graphql-mesh/fusion-runtime';
|
|
1
|
+
import { UnifiedGraphHandlerOpts, UnifiedGraphHandlerResult, UnifiedGraphPlugin, Instrumentation as Instrumentation$2 } from '@graphql-mesh/fusion-runtime';
|
|
2
|
+
import { DisposableSymbols } from '@whatwg-node/disposablestack';
|
|
3
|
+
import { MaybePromise } from '@whatwg-node/promise-helpers';
|
|
4
|
+
import { Plugin, YogaInitialContext, Instrumentation as Instrumentation$1 } from 'graphql-yoga';
|
|
5
|
+
import { MeshFetch, KeyValueCache, MeshFetchRequestInit, Logger as Logger$1 } from '@graphql-mesh/types';
|
|
6
|
+
import { FetchInstrumentation } from '@graphql-mesh/utils';
|
|
7
|
+
import { ExecutionRequest, MaybePromise as MaybePromise$1 } from '@graphql-tools/utils';
|
|
8
|
+
import { GraphQLResolveInfo } from 'graphql/type';
|
|
9
|
+
import { QueryPlan } from '@graphql-hive/router-query-planner';
|
|
2
10
|
|
|
3
11
|
declare function unifiedGraphHandler(opts: UnifiedGraphHandlerOpts): UnifiedGraphHandlerResult;
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
type MaybeLazy<T> = T | (() => T);
|
|
14
|
+
type AttributeValue = any;
|
|
15
|
+
type Attributes = AttributeValue[] | {
|
|
16
|
+
[key: string | number]: AttributeValue;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface LogWriter {
|
|
20
|
+
write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void | Promise<void>;
|
|
21
|
+
flush?(): void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
25
|
+
interface LoggerOptions {
|
|
26
|
+
/**
|
|
27
|
+
* The minimum log level to log.
|
|
28
|
+
*
|
|
29
|
+
* Providing `false` will disable all logging.
|
|
30
|
+
*
|
|
31
|
+
* Provided function will always be invoked to get the current log level.
|
|
32
|
+
*
|
|
33
|
+
* @default env.LOG_LEVEL || env.DEBUG ? 'debug' : 'info'
|
|
34
|
+
*/
|
|
35
|
+
level?: MaybeLazy<LogLevel | false>;
|
|
36
|
+
/** A prefix to include in every log's message. */
|
|
37
|
+
prefix?: string;
|
|
38
|
+
/**
|
|
39
|
+
* The attributes to include in all logs. Is mainly used to pass the parent
|
|
40
|
+
* attributes when creating {@link Logger.child child loggers}.
|
|
41
|
+
*/
|
|
42
|
+
attrs?: Attributes;
|
|
43
|
+
/**
|
|
44
|
+
* The log writers to use when writing logs.
|
|
45
|
+
*
|
|
46
|
+
* @default env.LOG_JSON ? [new JSONLogWriter()] : [new ConsoleLogWriter()]
|
|
47
|
+
*/
|
|
48
|
+
writers?: [LogWriter, ...LogWriter[]];
|
|
49
|
+
}
|
|
50
|
+
declare class Logger implements AsyncDisposable {
|
|
51
|
+
#private;
|
|
52
|
+
constructor(opts?: LoggerOptions);
|
|
53
|
+
/** The prefix that's prepended to each log message. */
|
|
54
|
+
get prefix(): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* The attributes that are added to each log. If the log itself contains
|
|
57
|
+
* attributes with keys existing in {@link attrs}, the log's attributes will
|
|
58
|
+
* override.
|
|
59
|
+
*/
|
|
60
|
+
get attrs(): Attributes | undefined;
|
|
61
|
+
/** The current {@link LogLevel} of the logger. You can change the level using the {@link setLevel} method. */
|
|
62
|
+
get level(): false | LogLevel;
|
|
63
|
+
/**
|
|
64
|
+
* Sets the new {@link LogLevel} of the logger. All subsequent logs, and {@link child child loggers} whose
|
|
65
|
+
* level did not change, will respect the new level.
|
|
66
|
+
*/
|
|
67
|
+
setLevel(level: MaybeLazy<LogLevel | false>): void;
|
|
68
|
+
write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void;
|
|
69
|
+
flush(): Promise<void> | undefined;
|
|
70
|
+
[DisposableSymbols.asyncDispose](): Promise<void | undefined>;
|
|
71
|
+
child(prefix: string): Logger;
|
|
72
|
+
child(attrs: Attributes, prefix?: string): Logger;
|
|
73
|
+
log(level: LogLevel): void;
|
|
74
|
+
log(level: LogLevel, attrs: MaybeLazy<Attributes>): void;
|
|
75
|
+
log(level: LogLevel, msg: string, ...interpol: unknown[]): void;
|
|
76
|
+
log(level: LogLevel, attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
77
|
+
trace(): void;
|
|
78
|
+
trace(attrs: MaybeLazy<Attributes>): void;
|
|
79
|
+
trace(msg: string, ...interpol: unknown[]): void;
|
|
80
|
+
trace(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
81
|
+
debug(): void;
|
|
82
|
+
debug(attrs: MaybeLazy<Attributes>): void;
|
|
83
|
+
debug(msg: string, ...interpol: unknown[]): void;
|
|
84
|
+
debug(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
85
|
+
info(): void;
|
|
86
|
+
info(attrs: MaybeLazy<Attributes>): void;
|
|
87
|
+
info(msg: string, ...interpol: unknown[]): void;
|
|
88
|
+
info(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
89
|
+
warn(): void;
|
|
90
|
+
warn(attrs: MaybeLazy<Attributes>): void;
|
|
91
|
+
warn(msg: string, ...interpol: unknown[]): void;
|
|
92
|
+
warn(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
93
|
+
error(): void;
|
|
94
|
+
error(attrs: MaybeLazy<Attributes>): void;
|
|
95
|
+
error(msg: string, ...interpol: unknown[]): void;
|
|
96
|
+
error(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
type TopicDataMap = {
|
|
100
|
+
[topic: string]: any;
|
|
101
|
+
};
|
|
102
|
+
type PubSubListener<Data extends TopicDataMap, Topic extends keyof Data> = (data: Data[Topic]) => void;
|
|
103
|
+
interface PubSub<M extends TopicDataMap = TopicDataMap> {
|
|
104
|
+
/**
|
|
105
|
+
* Publish {@link data} for a {@link topic}.
|
|
106
|
+
* @returns `void` or a `Promise` that resolves when the data has been successfully published
|
|
107
|
+
*/
|
|
108
|
+
publish<Topic extends keyof M>(topic: Topic, data: M[Topic]): MaybePromise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* A distinct list of all topics that are currently subscribed to.
|
|
111
|
+
* Can be a promise to accomodate distributed systems where subscribers exist on other
|
|
112
|
+
* locations and we need to know about all of them.
|
|
113
|
+
*/
|
|
114
|
+
subscribedTopics(): MaybePromise<Iterable<keyof M>>;
|
|
115
|
+
/**
|
|
116
|
+
* Subscribe and listen to a {@link topic} receiving its data.
|
|
117
|
+
*
|
|
118
|
+
* If the {@link listener} is provided, it will be called whenever data is emitted for the {@link topic},
|
|
119
|
+
*
|
|
120
|
+
* @returns an unsubscribe function or a `Promise<unsubscribe function>` that resolves when the subscription is successfully established. the unsubscribe function returns `void` or a `Promise` that resolves on successful unsubscribe and subscription cleanup
|
|
121
|
+
*
|
|
122
|
+
* If the {@link listener} is not provided,
|
|
123
|
+
*
|
|
124
|
+
* @returns an `AsyncIterable` that yields data for the given {@link topic}
|
|
125
|
+
*/
|
|
126
|
+
subscribe<Topic extends keyof M>(topic: Topic): AsyncIterable<M[Topic]>;
|
|
127
|
+
subscribe<Topic extends keyof M>(topic: Topic, listener: PubSubListener<M, Topic>): MaybePromise<() => MaybePromise<void>>;
|
|
128
|
+
/**
|
|
129
|
+
* Closes active subscriptions and disposes of all resources. Publishing and subscribing after disposal
|
|
130
|
+
* is not possible and will throw an error if attempted.
|
|
131
|
+
*/
|
|
132
|
+
dispose(): MaybePromise<void>;
|
|
133
|
+
/** @see {@link dispose} */
|
|
134
|
+
[DisposableSymbols.asyncDispose](): Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface GatewayConfigContext {
|
|
138
|
+
/**
|
|
139
|
+
* WHATWG compatible Fetch implementation.
|
|
140
|
+
*/
|
|
141
|
+
fetch: MeshFetch;
|
|
142
|
+
/**
|
|
143
|
+
* The logger to use throught Hive and its plugins.
|
|
144
|
+
*/
|
|
145
|
+
log: Logger;
|
|
146
|
+
/**
|
|
147
|
+
* Current working directory.
|
|
148
|
+
* Note that working directory does not exist in serverless environments and will therefore be empty.
|
|
149
|
+
*/
|
|
150
|
+
cwd: string;
|
|
151
|
+
/**
|
|
152
|
+
* Event bus for pub/sub.
|
|
153
|
+
*/
|
|
154
|
+
pubsub?: PubSub;
|
|
155
|
+
/**
|
|
156
|
+
* Cache Storage
|
|
157
|
+
*/
|
|
158
|
+
cache?: KeyValueCache;
|
|
159
|
+
}
|
|
160
|
+
interface GatewayContext extends GatewayConfigContext, YogaInitialContext {
|
|
161
|
+
/**
|
|
162
|
+
* Environment agnostic HTTP headers provided with the request.
|
|
163
|
+
*/
|
|
164
|
+
headers: Record<string, string>;
|
|
165
|
+
/**
|
|
166
|
+
* Runtime context available within WebSocket connections.
|
|
167
|
+
*/
|
|
168
|
+
connectionParams?: Record<string, string>;
|
|
169
|
+
}
|
|
170
|
+
type GatewayPlugin<TPluginContext extends Record<string, any> = Record<string, any>, TContext extends Record<string, any> = Record<string, any>> = Plugin<Partial<TPluginContext> & GatewayContext & TContext, GatewayConfigContext> & UnifiedGraphPlugin<Partial<TPluginContext> & GatewayContext & TContext> & {
|
|
171
|
+
onFetch?: OnFetchHook<Partial<TPluginContext> & TContext>;
|
|
172
|
+
onCacheGet?: OnCacheGetHook;
|
|
173
|
+
onCacheSet?: OnCacheSetHook;
|
|
174
|
+
onCacheDelete?: OnCacheDeleteHook;
|
|
175
|
+
/**
|
|
176
|
+
* An Instrumentation instance that will wrap each phases of the request pipeline.
|
|
177
|
+
* This should be used primarily as an observability tool (for monitoring, tracing, etc...).
|
|
178
|
+
*
|
|
179
|
+
* Note: The wrapped functions in instrumentation should always be called. Use hooks to
|
|
180
|
+
* conditionally skip a phase.
|
|
181
|
+
*/
|
|
182
|
+
instrumentation?: Instrumentation<TPluginContext & TContext & GatewayContext>;
|
|
183
|
+
};
|
|
184
|
+
interface OnFetchHookPayload<TContext> {
|
|
185
|
+
url: string;
|
|
186
|
+
setURL(url: URL | string): void;
|
|
187
|
+
options: MeshFetchRequestInit;
|
|
188
|
+
setOptions(options: MeshFetchRequestInit): void;
|
|
189
|
+
/**
|
|
190
|
+
* The context is not available in cases where "fetch" is done in
|
|
191
|
+
* order to pull a supergraph or do some internal work.
|
|
192
|
+
*
|
|
193
|
+
* The logger will be available in all cases.
|
|
194
|
+
*/
|
|
195
|
+
context: (GatewayContext & TContext) | {
|
|
196
|
+
log: Logger;
|
|
197
|
+
};
|
|
198
|
+
/** @deprecated Please use `log` from the {@link context} instead. */
|
|
199
|
+
logger: Logger$1;
|
|
200
|
+
info: GraphQLResolveInfo;
|
|
201
|
+
fetchFn: MeshFetch;
|
|
202
|
+
setFetchFn: (fetchFn: MeshFetch) => void;
|
|
203
|
+
executionRequest?: ExecutionRequest;
|
|
204
|
+
endResponse: (response$: MaybePromise$1<Response>) => void;
|
|
205
|
+
}
|
|
206
|
+
interface OnFetchHookDonePayload {
|
|
207
|
+
response: Response;
|
|
208
|
+
setResponse: (response: Response) => void;
|
|
209
|
+
}
|
|
210
|
+
type OnFetchHookDone = (payload: OnFetchHookDonePayload) => MaybePromise$1<void>;
|
|
211
|
+
type OnFetchHook<TContext> = (payload: OnFetchHookPayload<TContext>) => MaybePromise$1<void | OnFetchHookDone>;
|
|
212
|
+
type OnCacheGetHook = (payload: OnCacheGetHookEventPayload) => MaybePromise$1<OnCacheGetHookResult | void>;
|
|
213
|
+
interface OnCacheGetHookEventPayload {
|
|
214
|
+
cache: KeyValueCache;
|
|
215
|
+
key: string;
|
|
216
|
+
ttl?: number;
|
|
217
|
+
}
|
|
218
|
+
interface OnCacheGetHookResult {
|
|
219
|
+
onCacheHit?: OnCacheHitHook;
|
|
220
|
+
onCacheMiss?: OnCacheMissHook;
|
|
221
|
+
onCacheGetError?: OnCacheErrorHook;
|
|
222
|
+
}
|
|
223
|
+
type OnCacheErrorHook = (payload: OnCacheErrorHookPayload) => void;
|
|
224
|
+
interface OnCacheErrorHookPayload {
|
|
225
|
+
error: Error;
|
|
226
|
+
}
|
|
227
|
+
type OnCacheHitHook = (payload: OnCacheHitHookEventPayload) => void;
|
|
228
|
+
interface OnCacheHitHookEventPayload {
|
|
229
|
+
value: any;
|
|
230
|
+
}
|
|
231
|
+
type OnCacheMissHook = () => void;
|
|
232
|
+
type OnCacheSetHook = (payload: OnCacheSetHookEventPayload) => MaybePromise$1<OnCacheSetHookResult | void>;
|
|
233
|
+
interface OnCacheSetHookResult {
|
|
234
|
+
onCacheSetDone?: () => void;
|
|
235
|
+
onCacheSetError?: OnCacheErrorHook;
|
|
236
|
+
}
|
|
237
|
+
interface OnCacheSetHookEventPayload {
|
|
238
|
+
cache: KeyValueCache;
|
|
239
|
+
key: string;
|
|
240
|
+
value: any;
|
|
241
|
+
ttl?: number;
|
|
242
|
+
}
|
|
243
|
+
type OnCacheDeleteHook = (payload: OnCacheDeleteHookEventPayload) => MaybePromise$1<OnCacheDeleteHookResult | void>;
|
|
244
|
+
interface OnCacheDeleteHookResult {
|
|
245
|
+
onCacheDeleteDone?: () => void;
|
|
246
|
+
onCacheDeleteError?: OnCacheErrorHook;
|
|
247
|
+
}
|
|
248
|
+
interface OnCacheDeleteHookEventPayload {
|
|
249
|
+
cache: KeyValueCache;
|
|
250
|
+
key: string;
|
|
251
|
+
}
|
|
252
|
+
type Instrumentation<TContext extends Record<string, any>> = Instrumentation$1<TContext> & Instrumentation$2 & FetchInstrumentation;
|
|
253
|
+
|
|
254
|
+
interface QueryPlanOptions {
|
|
255
|
+
/** Callback when the query plan has been successfuly generated. */
|
|
256
|
+
onQueryPlan?(queryPlan: QueryPlan): void;
|
|
257
|
+
/** Exposing the query plan inside the GraphQL result extensions. */
|
|
258
|
+
expose?: boolean | ((request: Request) => boolean);
|
|
259
|
+
}
|
|
260
|
+
declare function useQueryPlan(opts?: QueryPlanOptions): GatewayPlugin;
|
|
261
|
+
|
|
262
|
+
export { type QueryPlanOptions, unifiedGraphHandler, useQueryPlan };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,262 @@
|
|
|
1
|
-
import { UnifiedGraphHandlerOpts, UnifiedGraphHandlerResult } from '@graphql-mesh/fusion-runtime';
|
|
1
|
+
import { UnifiedGraphHandlerOpts, UnifiedGraphHandlerResult, UnifiedGraphPlugin, Instrumentation as Instrumentation$2 } from '@graphql-mesh/fusion-runtime';
|
|
2
|
+
import { DisposableSymbols } from '@whatwg-node/disposablestack';
|
|
3
|
+
import { MaybePromise } from '@whatwg-node/promise-helpers';
|
|
4
|
+
import { Plugin, YogaInitialContext, Instrumentation as Instrumentation$1 } from 'graphql-yoga';
|
|
5
|
+
import { MeshFetch, KeyValueCache, MeshFetchRequestInit, Logger as Logger$1 } from '@graphql-mesh/types';
|
|
6
|
+
import { FetchInstrumentation } from '@graphql-mesh/utils';
|
|
7
|
+
import { ExecutionRequest, MaybePromise as MaybePromise$1 } from '@graphql-tools/utils';
|
|
8
|
+
import { GraphQLResolveInfo } from 'graphql/type';
|
|
9
|
+
import { QueryPlan } from '@graphql-hive/router-query-planner';
|
|
2
10
|
|
|
3
11
|
declare function unifiedGraphHandler(opts: UnifiedGraphHandlerOpts): UnifiedGraphHandlerResult;
|
|
4
12
|
|
|
5
|
-
|
|
13
|
+
type MaybeLazy<T> = T | (() => T);
|
|
14
|
+
type AttributeValue = any;
|
|
15
|
+
type Attributes = AttributeValue[] | {
|
|
16
|
+
[key: string | number]: AttributeValue;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
interface LogWriter {
|
|
20
|
+
write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void | Promise<void>;
|
|
21
|
+
flush?(): void | Promise<void>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';
|
|
25
|
+
interface LoggerOptions {
|
|
26
|
+
/**
|
|
27
|
+
* The minimum log level to log.
|
|
28
|
+
*
|
|
29
|
+
* Providing `false` will disable all logging.
|
|
30
|
+
*
|
|
31
|
+
* Provided function will always be invoked to get the current log level.
|
|
32
|
+
*
|
|
33
|
+
* @default env.LOG_LEVEL || env.DEBUG ? 'debug' : 'info'
|
|
34
|
+
*/
|
|
35
|
+
level?: MaybeLazy<LogLevel | false>;
|
|
36
|
+
/** A prefix to include in every log's message. */
|
|
37
|
+
prefix?: string;
|
|
38
|
+
/**
|
|
39
|
+
* The attributes to include in all logs. Is mainly used to pass the parent
|
|
40
|
+
* attributes when creating {@link Logger.child child loggers}.
|
|
41
|
+
*/
|
|
42
|
+
attrs?: Attributes;
|
|
43
|
+
/**
|
|
44
|
+
* The log writers to use when writing logs.
|
|
45
|
+
*
|
|
46
|
+
* @default env.LOG_JSON ? [new JSONLogWriter()] : [new ConsoleLogWriter()]
|
|
47
|
+
*/
|
|
48
|
+
writers?: [LogWriter, ...LogWriter[]];
|
|
49
|
+
}
|
|
50
|
+
declare class Logger implements AsyncDisposable {
|
|
51
|
+
#private;
|
|
52
|
+
constructor(opts?: LoggerOptions);
|
|
53
|
+
/** The prefix that's prepended to each log message. */
|
|
54
|
+
get prefix(): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* The attributes that are added to each log. If the log itself contains
|
|
57
|
+
* attributes with keys existing in {@link attrs}, the log's attributes will
|
|
58
|
+
* override.
|
|
59
|
+
*/
|
|
60
|
+
get attrs(): Attributes | undefined;
|
|
61
|
+
/** The current {@link LogLevel} of the logger. You can change the level using the {@link setLevel} method. */
|
|
62
|
+
get level(): false | LogLevel;
|
|
63
|
+
/**
|
|
64
|
+
* Sets the new {@link LogLevel} of the logger. All subsequent logs, and {@link child child loggers} whose
|
|
65
|
+
* level did not change, will respect the new level.
|
|
66
|
+
*/
|
|
67
|
+
setLevel(level: MaybeLazy<LogLevel | false>): void;
|
|
68
|
+
write(level: LogLevel, attrs: Attributes | null | undefined, msg: string | null | undefined): void;
|
|
69
|
+
flush(): Promise<void> | undefined;
|
|
70
|
+
[DisposableSymbols.asyncDispose](): Promise<void | undefined>;
|
|
71
|
+
child(prefix: string): Logger;
|
|
72
|
+
child(attrs: Attributes, prefix?: string): Logger;
|
|
73
|
+
log(level: LogLevel): void;
|
|
74
|
+
log(level: LogLevel, attrs: MaybeLazy<Attributes>): void;
|
|
75
|
+
log(level: LogLevel, msg: string, ...interpol: unknown[]): void;
|
|
76
|
+
log(level: LogLevel, attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
77
|
+
trace(): void;
|
|
78
|
+
trace(attrs: MaybeLazy<Attributes>): void;
|
|
79
|
+
trace(msg: string, ...interpol: unknown[]): void;
|
|
80
|
+
trace(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
81
|
+
debug(): void;
|
|
82
|
+
debug(attrs: MaybeLazy<Attributes>): void;
|
|
83
|
+
debug(msg: string, ...interpol: unknown[]): void;
|
|
84
|
+
debug(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
85
|
+
info(): void;
|
|
86
|
+
info(attrs: MaybeLazy<Attributes>): void;
|
|
87
|
+
info(msg: string, ...interpol: unknown[]): void;
|
|
88
|
+
info(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
89
|
+
warn(): void;
|
|
90
|
+
warn(attrs: MaybeLazy<Attributes>): void;
|
|
91
|
+
warn(msg: string, ...interpol: unknown[]): void;
|
|
92
|
+
warn(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
93
|
+
error(): void;
|
|
94
|
+
error(attrs: MaybeLazy<Attributes>): void;
|
|
95
|
+
error(msg: string, ...interpol: unknown[]): void;
|
|
96
|
+
error(attrs: MaybeLazy<Attributes>, msg: string, ...interpol: unknown[]): void;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
type TopicDataMap = {
|
|
100
|
+
[topic: string]: any;
|
|
101
|
+
};
|
|
102
|
+
type PubSubListener<Data extends TopicDataMap, Topic extends keyof Data> = (data: Data[Topic]) => void;
|
|
103
|
+
interface PubSub<M extends TopicDataMap = TopicDataMap> {
|
|
104
|
+
/**
|
|
105
|
+
* Publish {@link data} for a {@link topic}.
|
|
106
|
+
* @returns `void` or a `Promise` that resolves when the data has been successfully published
|
|
107
|
+
*/
|
|
108
|
+
publish<Topic extends keyof M>(topic: Topic, data: M[Topic]): MaybePromise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* A distinct list of all topics that are currently subscribed to.
|
|
111
|
+
* Can be a promise to accomodate distributed systems where subscribers exist on other
|
|
112
|
+
* locations and we need to know about all of them.
|
|
113
|
+
*/
|
|
114
|
+
subscribedTopics(): MaybePromise<Iterable<keyof M>>;
|
|
115
|
+
/**
|
|
116
|
+
* Subscribe and listen to a {@link topic} receiving its data.
|
|
117
|
+
*
|
|
118
|
+
* If the {@link listener} is provided, it will be called whenever data is emitted for the {@link topic},
|
|
119
|
+
*
|
|
120
|
+
* @returns an unsubscribe function or a `Promise<unsubscribe function>` that resolves when the subscription is successfully established. the unsubscribe function returns `void` or a `Promise` that resolves on successful unsubscribe and subscription cleanup
|
|
121
|
+
*
|
|
122
|
+
* If the {@link listener} is not provided,
|
|
123
|
+
*
|
|
124
|
+
* @returns an `AsyncIterable` that yields data for the given {@link topic}
|
|
125
|
+
*/
|
|
126
|
+
subscribe<Topic extends keyof M>(topic: Topic): AsyncIterable<M[Topic]>;
|
|
127
|
+
subscribe<Topic extends keyof M>(topic: Topic, listener: PubSubListener<M, Topic>): MaybePromise<() => MaybePromise<void>>;
|
|
128
|
+
/**
|
|
129
|
+
* Closes active subscriptions and disposes of all resources. Publishing and subscribing after disposal
|
|
130
|
+
* is not possible and will throw an error if attempted.
|
|
131
|
+
*/
|
|
132
|
+
dispose(): MaybePromise<void>;
|
|
133
|
+
/** @see {@link dispose} */
|
|
134
|
+
[DisposableSymbols.asyncDispose](): Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface GatewayConfigContext {
|
|
138
|
+
/**
|
|
139
|
+
* WHATWG compatible Fetch implementation.
|
|
140
|
+
*/
|
|
141
|
+
fetch: MeshFetch;
|
|
142
|
+
/**
|
|
143
|
+
* The logger to use throught Hive and its plugins.
|
|
144
|
+
*/
|
|
145
|
+
log: Logger;
|
|
146
|
+
/**
|
|
147
|
+
* Current working directory.
|
|
148
|
+
* Note that working directory does not exist in serverless environments and will therefore be empty.
|
|
149
|
+
*/
|
|
150
|
+
cwd: string;
|
|
151
|
+
/**
|
|
152
|
+
* Event bus for pub/sub.
|
|
153
|
+
*/
|
|
154
|
+
pubsub?: PubSub;
|
|
155
|
+
/**
|
|
156
|
+
* Cache Storage
|
|
157
|
+
*/
|
|
158
|
+
cache?: KeyValueCache;
|
|
159
|
+
}
|
|
160
|
+
interface GatewayContext extends GatewayConfigContext, YogaInitialContext {
|
|
161
|
+
/**
|
|
162
|
+
* Environment agnostic HTTP headers provided with the request.
|
|
163
|
+
*/
|
|
164
|
+
headers: Record<string, string>;
|
|
165
|
+
/**
|
|
166
|
+
* Runtime context available within WebSocket connections.
|
|
167
|
+
*/
|
|
168
|
+
connectionParams?: Record<string, string>;
|
|
169
|
+
}
|
|
170
|
+
type GatewayPlugin<TPluginContext extends Record<string, any> = Record<string, any>, TContext extends Record<string, any> = Record<string, any>> = Plugin<Partial<TPluginContext> & GatewayContext & TContext, GatewayConfigContext> & UnifiedGraphPlugin<Partial<TPluginContext> & GatewayContext & TContext> & {
|
|
171
|
+
onFetch?: OnFetchHook<Partial<TPluginContext> & TContext>;
|
|
172
|
+
onCacheGet?: OnCacheGetHook;
|
|
173
|
+
onCacheSet?: OnCacheSetHook;
|
|
174
|
+
onCacheDelete?: OnCacheDeleteHook;
|
|
175
|
+
/**
|
|
176
|
+
* An Instrumentation instance that will wrap each phases of the request pipeline.
|
|
177
|
+
* This should be used primarily as an observability tool (for monitoring, tracing, etc...).
|
|
178
|
+
*
|
|
179
|
+
* Note: The wrapped functions in instrumentation should always be called. Use hooks to
|
|
180
|
+
* conditionally skip a phase.
|
|
181
|
+
*/
|
|
182
|
+
instrumentation?: Instrumentation<TPluginContext & TContext & GatewayContext>;
|
|
183
|
+
};
|
|
184
|
+
interface OnFetchHookPayload<TContext> {
|
|
185
|
+
url: string;
|
|
186
|
+
setURL(url: URL | string): void;
|
|
187
|
+
options: MeshFetchRequestInit;
|
|
188
|
+
setOptions(options: MeshFetchRequestInit): void;
|
|
189
|
+
/**
|
|
190
|
+
* The context is not available in cases where "fetch" is done in
|
|
191
|
+
* order to pull a supergraph or do some internal work.
|
|
192
|
+
*
|
|
193
|
+
* The logger will be available in all cases.
|
|
194
|
+
*/
|
|
195
|
+
context: (GatewayContext & TContext) | {
|
|
196
|
+
log: Logger;
|
|
197
|
+
};
|
|
198
|
+
/** @deprecated Please use `log` from the {@link context} instead. */
|
|
199
|
+
logger: Logger$1;
|
|
200
|
+
info: GraphQLResolveInfo;
|
|
201
|
+
fetchFn: MeshFetch;
|
|
202
|
+
setFetchFn: (fetchFn: MeshFetch) => void;
|
|
203
|
+
executionRequest?: ExecutionRequest;
|
|
204
|
+
endResponse: (response$: MaybePromise$1<Response>) => void;
|
|
205
|
+
}
|
|
206
|
+
interface OnFetchHookDonePayload {
|
|
207
|
+
response: Response;
|
|
208
|
+
setResponse: (response: Response) => void;
|
|
209
|
+
}
|
|
210
|
+
type OnFetchHookDone = (payload: OnFetchHookDonePayload) => MaybePromise$1<void>;
|
|
211
|
+
type OnFetchHook<TContext> = (payload: OnFetchHookPayload<TContext>) => MaybePromise$1<void | OnFetchHookDone>;
|
|
212
|
+
type OnCacheGetHook = (payload: OnCacheGetHookEventPayload) => MaybePromise$1<OnCacheGetHookResult | void>;
|
|
213
|
+
interface OnCacheGetHookEventPayload {
|
|
214
|
+
cache: KeyValueCache;
|
|
215
|
+
key: string;
|
|
216
|
+
ttl?: number;
|
|
217
|
+
}
|
|
218
|
+
interface OnCacheGetHookResult {
|
|
219
|
+
onCacheHit?: OnCacheHitHook;
|
|
220
|
+
onCacheMiss?: OnCacheMissHook;
|
|
221
|
+
onCacheGetError?: OnCacheErrorHook;
|
|
222
|
+
}
|
|
223
|
+
type OnCacheErrorHook = (payload: OnCacheErrorHookPayload) => void;
|
|
224
|
+
interface OnCacheErrorHookPayload {
|
|
225
|
+
error: Error;
|
|
226
|
+
}
|
|
227
|
+
type OnCacheHitHook = (payload: OnCacheHitHookEventPayload) => void;
|
|
228
|
+
interface OnCacheHitHookEventPayload {
|
|
229
|
+
value: any;
|
|
230
|
+
}
|
|
231
|
+
type OnCacheMissHook = () => void;
|
|
232
|
+
type OnCacheSetHook = (payload: OnCacheSetHookEventPayload) => MaybePromise$1<OnCacheSetHookResult | void>;
|
|
233
|
+
interface OnCacheSetHookResult {
|
|
234
|
+
onCacheSetDone?: () => void;
|
|
235
|
+
onCacheSetError?: OnCacheErrorHook;
|
|
236
|
+
}
|
|
237
|
+
interface OnCacheSetHookEventPayload {
|
|
238
|
+
cache: KeyValueCache;
|
|
239
|
+
key: string;
|
|
240
|
+
value: any;
|
|
241
|
+
ttl?: number;
|
|
242
|
+
}
|
|
243
|
+
type OnCacheDeleteHook = (payload: OnCacheDeleteHookEventPayload) => MaybePromise$1<OnCacheDeleteHookResult | void>;
|
|
244
|
+
interface OnCacheDeleteHookResult {
|
|
245
|
+
onCacheDeleteDone?: () => void;
|
|
246
|
+
onCacheDeleteError?: OnCacheErrorHook;
|
|
247
|
+
}
|
|
248
|
+
interface OnCacheDeleteHookEventPayload {
|
|
249
|
+
cache: KeyValueCache;
|
|
250
|
+
key: string;
|
|
251
|
+
}
|
|
252
|
+
type Instrumentation<TContext extends Record<string, any>> = Instrumentation$1<TContext> & Instrumentation$2 & FetchInstrumentation;
|
|
253
|
+
|
|
254
|
+
interface QueryPlanOptions {
|
|
255
|
+
/** Callback when the query plan has been successfuly generated. */
|
|
256
|
+
onQueryPlan?(queryPlan: QueryPlan): void;
|
|
257
|
+
/** Exposing the query plan inside the GraphQL result extensions. */
|
|
258
|
+
expose?: boolean | ((request: Request) => boolean);
|
|
259
|
+
}
|
|
260
|
+
declare function useQueryPlan(opts?: QueryPlanOptions): GatewayPlugin;
|
|
261
|
+
|
|
262
|
+
export { type QueryPlanOptions, unifiedGraphHandler, useQueryPlan };
|
package/dist/index.js
CHANGED
|
@@ -1069,6 +1069,7 @@ function projectRequires(requiresSelections, entity, supergraphSchema) {
|
|
|
1069
1069
|
return result;
|
|
1070
1070
|
}
|
|
1071
1071
|
|
|
1072
|
+
const queryPlanForExecutionRequestContext = /* @__PURE__ */ new WeakMap();
|
|
1072
1073
|
function getLazyValue(factory) {
|
|
1073
1074
|
let _value;
|
|
1074
1075
|
return function() {
|
|
@@ -1139,52 +1140,59 @@ function unifiedGraphHandler(opts) {
|
|
|
1139
1140
|
executionRequest.document,
|
|
1140
1141
|
executionRequest.operationName || null
|
|
1141
1142
|
),
|
|
1142
|
-
(queryPlan) =>
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1143
|
+
(queryPlan) => {
|
|
1144
|
+
queryPlanForExecutionRequestContext.set(
|
|
1145
|
+
// setter like getter
|
|
1146
|
+
executionRequest.context || executionRequest.document,
|
|
1147
|
+
queryPlan
|
|
1148
|
+
);
|
|
1149
|
+
return executeQueryPlan({
|
|
1150
|
+
supergraphSchema,
|
|
1151
|
+
executionRequest,
|
|
1152
|
+
onSubgraphExecute(subgraphName, executionRequest2) {
|
|
1153
|
+
const subschema = getSubschema(subgraphName);
|
|
1154
|
+
if (subschema.transforms?.length) {
|
|
1155
|
+
const transforms = subschema.transforms;
|
|
1156
|
+
const transformationContext = /* @__PURE__ */ Object.create(null);
|
|
1157
|
+
for (const transform of transforms) {
|
|
1158
|
+
if (transform.transformRequest) {
|
|
1159
|
+
executionRequest2 = transform.transformRequest(
|
|
1160
|
+
executionRequest2,
|
|
1161
|
+
void 0,
|
|
1162
|
+
transformationContext
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1157
1165
|
}
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1166
|
+
return handleMaybePromise(
|
|
1167
|
+
() => opts.onSubgraphExecute(subgraphName, executionRequest2),
|
|
1168
|
+
(executionResult) => {
|
|
1169
|
+
function handleResult(executionResult2) {
|
|
1170
|
+
for (const transform of transforms.toReversed()) {
|
|
1171
|
+
if (transform.transformResult) {
|
|
1172
|
+
executionResult2 = transform.transformResult(
|
|
1173
|
+
executionResult2,
|
|
1174
|
+
void 0,
|
|
1175
|
+
transformationContext
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1170
1178
|
}
|
|
1179
|
+
return executionResult2;
|
|
1171
1180
|
}
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
);
|
|
1181
|
+
if (isAsyncIterable(executionResult)) {
|
|
1182
|
+
return mapAsyncIterator(
|
|
1183
|
+
executionResult,
|
|
1184
|
+
(result) => handleResult(result)
|
|
1185
|
+
);
|
|
1186
|
+
}
|
|
1187
|
+
return handleResult(executionResult);
|
|
1179
1188
|
}
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
);
|
|
1183
|
-
}
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
})
|
|
1189
|
+
);
|
|
1190
|
+
}
|
|
1191
|
+
return opts.onSubgraphExecute(subgraphName, executionRequest2);
|
|
1192
|
+
},
|
|
1193
|
+
queryPlan
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1188
1196
|
);
|
|
1189
1197
|
}
|
|
1190
1198
|
};
|
|
@@ -1213,4 +1221,31 @@ function isIntrospection(document) {
|
|
|
1213
1221
|
return containsIntrospectionField || onlyQueryTypenameFields;
|
|
1214
1222
|
}
|
|
1215
1223
|
|
|
1216
|
-
|
|
1224
|
+
function useQueryPlan(opts = {}) {
|
|
1225
|
+
const { expose, onQueryPlan } = opts;
|
|
1226
|
+
return {
|
|
1227
|
+
onExecute({ context, args }) {
|
|
1228
|
+
return {
|
|
1229
|
+
onExecuteDone({ result, setResult }) {
|
|
1230
|
+
const queryPlan = queryPlanForExecutionRequestContext.get(
|
|
1231
|
+
// getter like setter
|
|
1232
|
+
context || args.document
|
|
1233
|
+
);
|
|
1234
|
+
onQueryPlan?.(queryPlan);
|
|
1235
|
+
const shouldExpose = typeof expose === "function" ? expose(context.request) : expose;
|
|
1236
|
+
if (shouldExpose && !isAsyncIterable(result)) {
|
|
1237
|
+
setResult({
|
|
1238
|
+
...result,
|
|
1239
|
+
extensions: {
|
|
1240
|
+
...result.extensions,
|
|
1241
|
+
queryPlan
|
|
1242
|
+
}
|
|
1243
|
+
});
|
|
1244
|
+
}
|
|
1245
|
+
}
|
|
1246
|
+
};
|
|
1247
|
+
}
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
export { unifiedGraphHandler, useQueryPlan };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-hive/router-runtime",
|
|
3
|
-
"version": "1.1.0-rc-
|
|
3
|
+
"version": "1.1.0-rc-aa2a330ec509cf750e8722741cb18aed3ad01793",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@envelop/core": "^5.4.0",
|
|
46
46
|
"@graphql-hive/router-query-planner": "^0.0.6",
|
|
47
|
-
"@graphql-mesh/fusion-runtime": "1.6.0-rc-
|
|
47
|
+
"@graphql-mesh/fusion-runtime": "1.6.0-rc-aa2a330ec509cf750e8722741cb18aed3ad01793",
|
|
48
48
|
"@graphql-mesh/transport-common": "^1.0.12",
|
|
49
49
|
"@graphql-tools/executor": "^1.4.13",
|
|
50
50
|
"@graphql-tools/executor-common": "^1.0.5",
|
|
51
|
-
"@graphql-tools/federation": "4.2.4-rc-
|
|
51
|
+
"@graphql-tools/federation": "4.2.4-rc-aa2a330ec509cf750e8722741cb18aed3ad01793",
|
|
52
52
|
"@graphql-tools/utils": "^10.10.3",
|
|
53
53
|
"@whatwg-node/promise-helpers": "^1.3.2"
|
|
54
54
|
},
|