@powerhousedao/reactor-api 6.0.0-dev.114 → 6.0.0-dev.115

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.
Files changed (25) hide show
  1. package/dist/src/graphql/gateway/adapter-gateway-mercurius.d.ts +17 -0
  2. package/dist/src/graphql/gateway/adapter-gateway-mercurius.d.ts.map +1 -0
  3. package/dist/src/graphql/gateway/adapter-gateway-mercurius.js +154 -0
  4. package/dist/src/graphql/gateway/adapter-gateway-mercurius.js.map +1 -0
  5. package/dist/src/graphql/gateway/adapter-http-fastify.d.ts +23 -0
  6. package/dist/src/graphql/gateway/adapter-http-fastify.d.ts.map +1 -0
  7. package/dist/src/graphql/gateway/adapter-http-fastify.js +228 -0
  8. package/dist/src/graphql/gateway/adapter-http-fastify.js.map +1 -0
  9. package/dist/src/graphql/gateway/factory.d.ts +2 -2
  10. package/dist/src/graphql/gateway/factory.d.ts.map +1 -1
  11. package/dist/src/graphql/gateway/factory.js +6 -0
  12. package/dist/src/graphql/gateway/factory.js.map +1 -1
  13. package/dist/test/gateway/adapter-gateway-mercurius.test.d.ts +2 -0
  14. package/dist/test/gateway/adapter-gateway-mercurius.test.d.ts.map +1 -0
  15. package/dist/test/gateway/adapter-gateway-mercurius.test.js +23 -0
  16. package/dist/test/gateway/adapter-gateway-mercurius.test.js.map +1 -0
  17. package/dist/test/gateway/adapter-http-fastify.test.d.ts +2 -0
  18. package/dist/test/gateway/adapter-http-fastify.test.d.ts.map +1 -0
  19. package/dist/test/gateway/adapter-http-fastify.test.js +17 -0
  20. package/dist/test/gateway/adapter-http-fastify.test.js.map +1 -0
  21. package/dist/tsconfig.tsbuildinfo +1 -1
  22. package/dist/vitest.config.d.ts.map +1 -1
  23. package/dist/vitest.config.js +1 -4
  24. package/dist/vitest.config.js.map +1 -1
  25. package/package.json +17 -11
@@ -0,0 +1,17 @@
1
+ import type { ILogger } from "document-model";
2
+ import type { GraphQLSchema } from "graphql";
3
+ import type http from "node:http";
4
+ import type { WebSocketServer } from "ws";
5
+ import type { Context } from "../types.js";
6
+ import type { FetchHandler, GatewayContextFactory, IGatewayAdapter, SubgraphDefinition, WsContextFactory, WsDisposer } from "./types.js";
7
+ export declare class MercuriusGatewayAdapter implements IGatewayAdapter<Context> {
8
+ #private;
9
+ constructor(logger: ILogger);
10
+ start(_httpServer: http.Server): Promise<void>;
11
+ createHandler(schema: GraphQLSchema, contextFactory: GatewayContextFactory<Context>): Promise<FetchHandler>;
12
+ createSupergraphHandler(getSubgraphs: () => SubgraphDefinition[], _httpServer: http.Server, contextFactory: GatewayContextFactory<Context>): Promise<FetchHandler>;
13
+ updateSupergraph(): Promise<void>;
14
+ attachWebSocket(wsServer: WebSocketServer, schema: GraphQLSchema, contextFactory: WsContextFactory<Context>): WsDisposer;
15
+ stop(): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=adapter-gateway-mercurius.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-gateway-mercurius.d.ts","sourceRoot":"","sources":["../../../../src/graphql/gateway/adapter-gateway-mercurius.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,IAAI,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACX,MAAM,YAAY,CAAC;AAmBpB,qBAAa,uBAAwB,YAAW,eAAe,CAAC,OAAO,CAAC;;gBAQ1D,MAAM,EAAE,OAAO;IAIrB,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9C,aAAa,CACjB,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,qBAAqB,CAAC,OAAO,CAAC,GAC7C,OAAO,CAAC,YAAY,CAAC;IAMlB,uBAAuB,CAC3B,YAAY,EAAE,MAAM,kBAAkB,EAAE,EACxC,WAAW,EAAE,IAAI,CAAC,MAAM,EACxB,cAAc,EAAE,qBAAqB,CAAC,OAAO,CAAC,GAC7C,OAAO,CAAC,YAAY,CAAC;IA4BlB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAavC,eAAe,CACb,QAAQ,EAAE,eAAe,EACzB,MAAM,EAAE,aAAa,EACrB,cAAc,EAAE,gBAAgB,CAAC,OAAO,CAAC,GACxC,UAAU;IAaP,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAU5B"}
@@ -0,0 +1,154 @@
1
+ import mercuriusGateway from "@mercuriusjs/gateway";
2
+ import Fastify from "fastify";
3
+ import mercurius from "mercurius";
4
+ import { AsyncLocalStorage } from "node:async_hooks";
5
+ import { useServer } from "../websocket.js";
6
+ /**
7
+ * Threads the original Fetch API Request through Mercurius's internal
8
+ * fastify.inject() call so that contextFactory (which uses the auth WeakMap
9
+ * from auth-middleware.ts) receives the same Request object that auth
10
+ * middleware populated before calling the handler.
11
+ */
12
+ const requestAls = new AsyncLocalStorage();
13
+ const mercuriusGatewayPlugin = mercuriusGateway;
14
+ export class MercuriusGatewayAdapter {
15
+ #logger;
16
+ #subgraphApps = [];
17
+ #supergraphApp = null;
18
+ #getSubgraphs = null;
19
+ #supergraphContextFactory = null;
20
+ constructor(logger) {
21
+ this.#logger = logger;
22
+ }
23
+ async start(_httpServer) {
24
+ // Mercurius instances are started lazily in createHandler /
25
+ // createSupergraphHandler — nothing to do here.
26
+ }
27
+ async createHandler(schema, contextFactory) {
28
+ const app = await buildMercuriusApp(schema, contextFactory, this.#logger);
29
+ this.#subgraphApps.push(app);
30
+ return buildFetchHandler(app);
31
+ }
32
+ async createSupergraphHandler(getSubgraphs, _httpServer, contextFactory) {
33
+ if (this.#supergraphApp) {
34
+ throw new Error("Supergraph is already running");
35
+ }
36
+ this.#getSubgraphs = getSubgraphs;
37
+ this.#supergraphContextFactory = contextFactory;
38
+ this.#supergraphApp = await buildGatewayApp(getSubgraphs(), contextFactory, this.#logger);
39
+ // Capture `this` so the returned handler always delegates to the *current*
40
+ // #supergraphApp, allowing updateSupergraph() to swap it atomically.
41
+ // eslint-disable-next-line @typescript-eslint/no-this-alias
42
+ const adapter = this;
43
+ return (request) => {
44
+ if (!adapter.#supergraphApp) {
45
+ return Promise.resolve(new Response("Gateway not ready", { status: 503 }));
46
+ }
47
+ return requestAls.run(request, () => injectRequest(adapter.#supergraphApp, request));
48
+ };
49
+ }
50
+ async updateSupergraph() {
51
+ if (!this.#getSubgraphs || !this.#supergraphContextFactory)
52
+ return;
53
+ const newApp = await buildGatewayApp(this.#getSubgraphs(), this.#supergraphContextFactory, this.#logger);
54
+ const oldApp = this.#supergraphApp;
55
+ // Swap atomically — in-flight requests on the old app finish normally.
56
+ this.#supergraphApp = newApp;
57
+ if (oldApp)
58
+ await oldApp.close();
59
+ }
60
+ attachWebSocket(wsServer, schema, contextFactory) {
61
+ // Use graphql-ws directly; Mercurius's own subscription transport is
62
+ // Fastify-specific and not applicable here.
63
+ return useServer({
64
+ schema,
65
+ context: async (ctx) => contextFactory(ctx.connectionParams ?? {}),
66
+ }, wsServer);
67
+ }
68
+ async stop() {
69
+ await Promise.all(this.#subgraphApps.map((app) => app.close()));
70
+ this.#subgraphApps.length = 0;
71
+ if (this.#supergraphApp) {
72
+ await this.#supergraphApp.close();
73
+ this.#supergraphApp = null;
74
+ }
75
+ this.#getSubgraphs = null;
76
+ this.#supergraphContextFactory = null;
77
+ }
78
+ }
79
+ // ── Fastify instance factories ────────────────────────────────────────────────
80
+ function makeContextFn(contextFactory, logger) {
81
+ return (_req, _reply) => {
82
+ const request = requestAls.getStore();
83
+ if (!request) {
84
+ logger.error("[mercurius] No Fetch Request in AsyncLocalStorage");
85
+ throw new Error("No Fetch Request in AsyncLocalStorage");
86
+ }
87
+ return contextFactory(request);
88
+ };
89
+ }
90
+ async function buildMercuriusApp(schema, contextFactory, logger) {
91
+ const app = Fastify({ logger: false });
92
+ await app.register(mercurius, {
93
+ schema,
94
+ graphiql: false,
95
+ context: makeContextFn(contextFactory, logger),
96
+ // Override _Service.sdl to rewrite "type Query/Mutation/Subscription {"
97
+ // as "extend type … {" so that @mercuriusjs/gateway v5 (which follows the
98
+ // Federation v1 convention of using extensionTypeMap) correctly maps root
99
+ // operation fields to this service during query planning.
100
+ resolvers: {
101
+ _Service: {
102
+ sdl: (parent) => (parent.sdl ?? "").replace(/\btype\s+(Query|Mutation|Subscription)\s*\{/g, "extend type $1 {"),
103
+ },
104
+ },
105
+ });
106
+ await app.ready();
107
+ return app;
108
+ }
109
+ /**
110
+ * Builds a Mercurius federation gateway that composes the given subgraph
111
+ * services. Each service URL must be reachable so that the gateway can fetch
112
+ * its SDL via `_service { sdl }` (Apollo Federation protocol).
113
+ */
114
+ async function buildGatewayApp(subgraphs, contextFactory, logger) {
115
+ const app = Fastify({ logger: false });
116
+ await app.register(mercuriusGatewayPlugin, {
117
+ gateway: {
118
+ services: subgraphs.map((s) => ({ name: s.name, url: s.url })),
119
+ },
120
+ graphiql: false,
121
+ context: makeContextFn(contextFactory, logger),
122
+ });
123
+ await app.ready();
124
+ return app;
125
+ }
126
+ // ── Fetch API bridge ──────────────────────────────────────────────────────────
127
+ function buildFetchHandler(app) {
128
+ return (request) => requestAls.run(request, () => injectRequest(app, request));
129
+ }
130
+ async function injectRequest(app, request) {
131
+ const body = request.method !== "GET" && request.method !== "HEAD"
132
+ ? await request.text()
133
+ : undefined;
134
+ const headers = {};
135
+ request.headers.forEach((value, key) => {
136
+ headers[key] = value;
137
+ });
138
+ const response = await app.inject({
139
+ method: request.method,
140
+ url: "/graphql",
141
+ headers,
142
+ payload: body,
143
+ });
144
+ const responseHeaders = {};
145
+ for (const [key, value] of Object.entries(response.headers)) {
146
+ if (value !== undefined)
147
+ responseHeaders[key] = String(value);
148
+ }
149
+ return new Response(response.payload, {
150
+ status: response.statusCode,
151
+ headers: responseHeaders,
152
+ });
153
+ }
154
+ //# sourceMappingURL=adapter-gateway-mercurius.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-gateway-mercurius.js","sourceRoot":"","sources":["../../../../src/graphql/gateway/adapter-gateway-mercurius.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { CorsOptions } from "cors";
2
+ import http from "node:http";
3
+ import type { FetchHandler, IHttpAdapter, TlsOptions } from "./types.js";
4
+ export declare class FastifyHttpAdapter implements IHttpAdapter {
5
+ #private;
6
+ get handle(): unknown;
7
+ setupMiddleware({ corsOptions, bodyLimit, }: {
8
+ corsOptions?: CorsOptions;
9
+ bodyLimit?: string;
10
+ }): void;
11
+ mount(path: string, handler: FetchHandler, { exact }?: {
12
+ exact?: boolean;
13
+ }): void;
14
+ getRoute(path: string, handler: (request: Request) => Response | Promise<Response>): void;
15
+ mountNodeRoute(method: "DELETE" | "GET" | "POST", path: string, handler: (req: http.IncomingMessage, res: http.ServerResponse, body?: unknown) => void): void;
16
+ mountRawMiddleware(middleware: unknown): void;
17
+ setupSentryErrorHandler(sentry: object): void;
18
+ listen(port: number, tls?: TlsOptions): Promise<http.Server>;
19
+ }
20
+ export declare function createFastifyHttpAdapter(): {
21
+ adapter: IHttpAdapter;
22
+ };
23
+ //# sourceMappingURL=adapter-http-fastify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-http-fastify.d.ts","sourceRoot":"","sources":["../../../../src/graphql/gateway/adapter-http-fastify.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAExC,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAkDzE,qBAAa,kBAAmB,YAAW,YAAY;;IAarD,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,eAAe,CAAC,EACd,WAAW,EACX,SAAkB,GACnB,EAAE;QACD,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,GAAG,IAAI;IAQR,KAAK,CACH,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,EACrB,EAAE,KAAa,EAAE,GAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAO,GAC1C,IAAI;IASP,QAAQ,CACN,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAC1D,IAAI;IAIP,cAAc,CACZ,MAAM,EAAE,QAAQ,GAAG,KAAK,GAAG,MAAM,EACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CACP,GAAG,EAAE,IAAI,CAAC,eAAe,EACzB,GAAG,EAAE,IAAI,CAAC,cAAc,EACxB,IAAI,CAAC,EAAE,OAAO,KACX,IAAI,GACR,IAAI;IAOP,kBAAkB,CAAC,UAAU,EAAE,OAAO,GAAG,IAAI;IAa7C,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQvC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;CAoInE;AA6CD,wBAAgB,wBAAwB,IAAI;IAAE,OAAO,EAAE,YAAY,CAAA;CAAE,CAEpE"}
@@ -0,0 +1,228 @@
1
+ import fastifyCors from "@fastify/cors";
2
+ import fastifyFormbody from "@fastify/formbody";
3
+ import fastifyMiddie from "@fastify/middie";
4
+ import devcert from "devcert";
5
+ import Fastify from "fastify";
6
+ import fs from "node:fs";
7
+ import http from "node:http";
8
+ import https from "node:https";
9
+ import nodePath from "node:path";
10
+ import { match } from "path-to-regexp";
11
+ /**
12
+ * Normalises a route path for path-to-regexp v8:
13
+ * - Collapses duplicate slashes (e.g. "//explorer" → "/explorer")
14
+ * - Converts legacy optional-param syntax ":param?" → "{/:param}?"
15
+ */
16
+ function normalizePath(path) {
17
+ return path.replace(/\/+/g, "/").replace(/:(\w+)\?/g, "{/:$1}");
18
+ }
19
+ /** Parses body-limit strings like "50mb" to bytes. */
20
+ function parseBodyLimit(limit) {
21
+ const m = /^(\d+(?:\.\d+)?)\s*(b|kb|mb|gb)?$/i.exec(limit.trim());
22
+ if (!m)
23
+ return 52_428_800; // 50 MB fallback
24
+ const n = parseFloat(m[1]);
25
+ const units = {
26
+ b: 1,
27
+ kb: 1_024,
28
+ mb: 1_048_576,
29
+ gb: 1_073_741_824,
30
+ };
31
+ return Math.round(n * (units[(m[2] ?? "b").toLowerCase()] ?? 1));
32
+ }
33
+ export class FastifyHttpAdapter {
34
+ // Dispatch maps — populated at any time (before or after listen).
35
+ #fetchRoutes = [];
36
+ #getRoutes = new Map();
37
+ // path → method → handler
38
+ #nodeRoutes = new Map();
39
+ // Ops that need the Fastify instance (CORS config, Connect middleware).
40
+ #setupOps = [];
41
+ #instance;
42
+ get handle() {
43
+ return this.#instance;
44
+ }
45
+ setupMiddleware({ corsOptions, bodyLimit = "50mb", }) {
46
+ this.#setupOps.push({
47
+ kind: "cors",
48
+ options: corsOptions,
49
+ bodyLimit: parseBodyLimit(bodyLimit),
50
+ });
51
+ }
52
+ mount(path, handler, { exact = false } = {}) {
53
+ this.#fetchRoutes.push({
54
+ handler,
55
+ // exact=false → exact path match; exact=true → prefix match.
56
+ matcher: match(normalizePath(path), { end: !exact }),
57
+ prefix: exact,
58
+ });
59
+ }
60
+ getRoute(path, handler) {
61
+ this.#getRoutes.set(path, { handler, matcher: match(normalizePath(path)) });
62
+ }
63
+ mountNodeRoute(method, path, handler) {
64
+ if (!this.#nodeRoutes.has(path)) {
65
+ this.#nodeRoutes.set(path, new Map());
66
+ }
67
+ this.#nodeRoutes.get(path).set(method, handler);
68
+ }
69
+ mountRawMiddleware(middleware) {
70
+ if (this.#instance) {
71
+ // @fastify/middie is always registered, so .use() is available post-listen.
72
+ this.#instance.use(middleware);
73
+ }
74
+ else {
75
+ this.#setupOps.push({ kind: "middie", middleware });
76
+ }
77
+ }
78
+ setupSentryErrorHandler(sentry) {
79
+ if (!this.#instance)
80
+ return;
81
+ const s = sentry;
82
+ s.setupFastifyErrorHandler(this.#instance);
83
+ }
84
+ async listen(port, tls) {
85
+ let httpServer;
86
+ if (tls === true) {
87
+ const { cert, key } = (await devcert.certificateFor("localhost"));
88
+ if (!cert || !key)
89
+ throw new Error("Invalid certificate generated");
90
+ httpServer = https.createServer({ cert, key });
91
+ }
92
+ else if (tls && "keyPath" in tls) {
93
+ const cwd = process.cwd();
94
+ httpServer = https.createServer({
95
+ key: fs.readFileSync(nodePath.join(cwd, tls.keyPath)),
96
+ cert: fs.readFileSync(nodePath.join(cwd, tls.certPath)),
97
+ });
98
+ }
99
+ else if (tls && "cert" in tls) {
100
+ httpServer = https.createServer({ cert: tls.cert, key: tls.key });
101
+ }
102
+ else {
103
+ httpServer = http.createServer();
104
+ }
105
+ const corsOp = this.#setupOps.find((op) => op.kind === "cors");
106
+ const bodyLimit = corsOp?.bodyLimit ?? 52_428_800;
107
+ const instance = Fastify({
108
+ serverFactory: (handler) => {
109
+ httpServer.on("request", handler);
110
+ return httpServer;
111
+ },
112
+ bodyLimit,
113
+ logger: false,
114
+ });
115
+ this.#instance = instance;
116
+ // Always register middie first so .use() is available post-listen.
117
+ await instance.register(fastifyMiddie);
118
+ await instance.register(fastifyFormbody);
119
+ for (const op of this.#setupOps) {
120
+ if (op.kind === "cors") {
121
+ await instance.register(fastifyCors, op.options);
122
+ }
123
+ else {
124
+ instance.use(op.middleware);
125
+ }
126
+ }
127
+ // Single catch-all route — all dispatching is done via the Maps above so
128
+ // that routes registered after listen() are picked up automatically.
129
+ // OPTIONS is excluded because @fastify/cors registers its own OPTIONS /*
130
+ // handler for preflight; including it here would cause a duplicate-route
131
+ // conflict at startup.
132
+ instance.route({
133
+ method: ["DELETE", "GET", "HEAD", "PATCH", "POST", "PUT"],
134
+ url: "/*",
135
+ handler: (req, reply) => this.#dispatch(req, reply),
136
+ });
137
+ await instance.ready();
138
+ return new Promise((resolve, reject) => {
139
+ httpServer.once("error", reject);
140
+ httpServer.listen(port, () => {
141
+ httpServer.off("error", reject);
142
+ resolve(httpServer);
143
+ });
144
+ });
145
+ }
146
+ #dispatch(req, reply) {
147
+ const pathname = new URL(req.url, "http://localhost").pathname;
148
+ const method = req.method.toUpperCase();
149
+ // 1. Node routes — exact path + method, handler manages raw response.
150
+ const nodeHandlers = this.#nodeRoutes.get(pathname);
151
+ if (nodeHandlers) {
152
+ const handler = nodeHandlers.get(method);
153
+ if (handler) {
154
+ reply.hijack();
155
+ handler(req.raw, reply.raw, req.body);
156
+ return;
157
+ }
158
+ }
159
+ // 2. GET-specific routes (health, explorer, etc.).
160
+ if (method === "GET") {
161
+ for (const entry of this.#getRoutes.values()) {
162
+ if (entry.matcher(pathname)) {
163
+ return this.#serveGetEntry(entry, req, reply);
164
+ }
165
+ }
166
+ }
167
+ // 3. Fetch routes (GraphQL handlers, SSE, etc.).
168
+ // Iterate in reverse so that the last-mounted handler wins when the same
169
+ // path is mounted more than once (e.g. supergraph remount after reload).
170
+ for (let i = this.#fetchRoutes.length - 1; i >= 0; i--) {
171
+ const entry = this.#fetchRoutes[i];
172
+ if (entry.matcher(pathname)) {
173
+ return serveFetchHandler(entry.handler, req, reply);
174
+ }
175
+ }
176
+ void reply.status(404).send({
177
+ message: `Route ${req.method}:${pathname} not found`,
178
+ error: "Not Found",
179
+ statusCode: 404,
180
+ });
181
+ }
182
+ async #serveGetEntry(entry, req, reply) {
183
+ const url = buildUrl(req);
184
+ const headers = buildHeaders(req);
185
+ const fetchReq = new Request(url, { method: "GET", headers });
186
+ const response = await entry.handler(fetchReq);
187
+ writeResponse(reply, response);
188
+ return reply.send(await response.text());
189
+ }
190
+ }
191
+ async function serveFetchHandler(handler, req, reply) {
192
+ const url = buildUrl(req);
193
+ const headers = buildHeaders(req);
194
+ let body;
195
+ if (req.method !== "GET" && req.method !== "HEAD" && req.body !== undefined) {
196
+ body = JSON.stringify(req.body);
197
+ }
198
+ const fetchRequest = new Request(url, { method: req.method, headers, body });
199
+ const response = await handler(fetchRequest);
200
+ writeResponse(reply, response);
201
+ return reply.send(await response.text());
202
+ }
203
+ function buildUrl(req) {
204
+ const host = req.headers.host ?? "localhost";
205
+ return `${req.protocol}://${host}${req.url}`;
206
+ }
207
+ function buildHeaders(req) {
208
+ const headers = new Headers();
209
+ for (const [key, value] of Object.entries(req.headers)) {
210
+ if (typeof value === "string") {
211
+ headers.set(key, value);
212
+ }
213
+ else if (Array.isArray(value)) {
214
+ headers.set(key, value.join(", "));
215
+ }
216
+ }
217
+ return headers;
218
+ }
219
+ function writeResponse(reply, response) {
220
+ void reply.status(response.status);
221
+ response.headers.forEach((value, key) => {
222
+ void reply.header(key, value);
223
+ });
224
+ }
225
+ export function createFastifyHttpAdapter() {
226
+ return { adapter: new FastifyHttpAdapter() };
227
+ }
228
+ //# sourceMappingURL=adapter-http-fastify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-http-fastify.js","sourceRoot":"","sources":["../../../../src/graphql/gateway/adapter-http-fastify.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAChD,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAC5C,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,OAAO,MAAM,SAAS,CAAC;AAG9B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,KAAK,EAAsC,MAAM,gBAAgB,CAAC;AAG3E;;;;GAIG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;AAClE,CAAC;AAED,sDAAsD;AACtD,SAAS,cAAc,CAAC,KAAa;IACnC,MAAM,CAAC,GAAG,oCAAoC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IAClE,IAAI,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC,CAAC,iBAAiB;IAC5C,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,KAAK,GAA2B;QACpC,CAAC,EAAE,CAAC;QACJ,EAAE,EAAE,KAAK;QACT,EAAE,EAAE,SAAS;QACb,EAAE,EAAE,aAAa;KAClB,CAAC;IACF,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACnE,CAAC;AA2BD,MAAM,OAAO,kBAAkB;IAC7B,kEAAkE;IACzD,YAAY,GAAiB,EAAE,CAAC;IAChC,UAAU,GAA0B,IAAI,GAAG,EAAE,CAAC;IACvD,0BAA0B;IACjB,WAAW,GAClB,IAAI,GAAG,EAAE,CAAC;IAEZ,wEAAwE;IAC/D,SAAS,GAAc,EAAE,CAAC;IAEnC,SAAS,CAA8B;IAEvC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED,eAAe,CAAC,EACd,WAAW,EACX,SAAS,GAAG,MAAM,GAInB;QACC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAClB,IAAI,EAAE,MAAM;YACZ,OAAO,EAAE,WAAW;YACpB,SAAS,EAAE,cAAc,CAAC,SAAS,CAAC;SACrC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CACH,IAAY,EACZ,OAAqB,EACrB,EAAE,KAAK,GAAG,KAAK,KAA0B,EAAE;QAE3C,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC;YACrB,OAAO;YACP,6DAA6D;YAC7D,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;YACpD,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;IACL,CAAC;IAED,QAAQ,CACN,IAAY,EACZ,OAA2D;QAE3D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,cAAc,CACZ,MAAiC,EACjC,IAAY,EACZ,OAIS;QAET,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAED,kBAAkB,CAAC,UAAmB;QACpC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,4EAA4E;YAE1E,IAAI,CAAC,SAGN,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACpB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,uBAAuB,CAAC,MAAc;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO;QAC5B,MAAM,CAAC,GAAG,MAET,CAAC;QACF,CAAC,CAAC,wBAAwB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,GAAgB;QACzC,IAAI,UAAuB,CAAC;QAE5B,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,OAAO,CAAC,cAAc,CAAC,WAAW,CAAC,CAG/D,CAAC;YACF,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YACpE,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC;QACjD,CAAC;aAAM,IAAI,GAAG,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;YAC1B,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC;gBAC9B,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrD,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;aACxD,CAAC,CAAC;QACL,CAAC;aAAM,IAAI,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;YAChC,UAAU,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QACnC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAChC,CAAC,EAAE,EAA4C,EAAE,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,CACrE,CAAC;QACF,MAAM,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,UAAU,CAAC;QAElD,MAAM,QAAQ,GAAG,OAAO,CAAC;YACvB,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE;gBACzB,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;gBAClC,OAAO,UAAU,CAAC;YACpB,CAAC;YACD,SAAS;YACT,MAAM,EAAE,KAAK;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;QAE1B,mEAAmE;QACnE,MAAM,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QACvC,MAAM,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAEzC,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAChC,IAAI,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACvB,MAAM,QAAQ,CAAC,QAAQ,CACrB,WAAW,EACX,EAAE,CAAC,OAA4C,CAChD,CAAC;YACJ,CAAC;iBAAM,CAAC;gBAEJ,QAGD,CAAC,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAED,yEAAyE;QACzE,qEAAqE;QACrE,yEAAyE;QACzE,yEAAyE;QACzE,uBAAuB;QACvB,QAAQ,CAAC,KAAK,CAAC;YACb,MAAM,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC;YACzD,GAAG,EAAE,IAAI;YACT,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,CAAC;SACpD,CAAC,CAAC;QAEH,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEvB,OAAO,IAAI,OAAO,CAAc,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAClD,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACjC,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;gBAC3B,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAChC,OAAO,CAAC,UAAU,CAAC,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;IAED,SAAS,CAAC,GAAmB,EAAE,KAAmB;QAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC,QAAQ,CAAC;QAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,WAAW,EAA+B,CAAC;QAErE,sEAAsE;QACtE,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,OAAO,EAAE,CAAC;gBACZ,KAAK,CAAC,MAAM,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;gBACtC,OAAO;YACT,CAAC;QACH,CAAC;QAED,mDAAmD;QACnD,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;YACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC5B,OAAO,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;QAED,iDAAiD;QACjD,yEAAyE;QACzE,yEAAyE;QACzE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACvD,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,CAAE,CAAC;YACpC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC5B,OAAO,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;QAED,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YAC1B,OAAO,EAAE,SAAS,GAAG,CAAC,MAAM,IAAI,QAAQ,YAAY;YACpD,KAAK,EAAE,WAAW;YAClB,UAAU,EAAE,GAAG;SAChB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc,CAClB,KAAe,EACf,GAAmB,EACnB,KAAmB;QAEnB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC/C,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF;AAED,KAAK,UAAU,iBAAiB,CAC9B,OAAqB,EACrB,GAAmB,EACnB,KAAmB;IAEnB,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,IAAwB,CAAC;IAC7B,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5E,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAED,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7E,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAC7C,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,QAAQ,CAAC,GAAmB;IACnC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;IAC7C,OAAO,GAAG,GAAG,CAAC,QAAQ,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,YAAY,CAAC,GAAmB;IACvC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,aAAa,CAAC,KAAmB,EAAE,QAAkB;IAC5D,KAAK,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACtC,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,OAAO,EAAE,OAAO,EAAE,IAAI,kBAAkB,EAAE,EAAE,CAAC;AAC/C,CAAC"}
@@ -1,8 +1,8 @@
1
1
  import type { ILogger } from "document-model";
2
2
  import type { Context } from "../types.js";
3
3
  import type { IGatewayAdapter, IHttpAdapter } from "./types.js";
4
- export type GatewayAdapterType = "apollo";
5
- export type HttpAdapterType = "express";
4
+ export type GatewayAdapterType = "apollo" | "mercurius";
5
+ export type HttpAdapterType = "express" | "fastify";
6
6
  export declare function createGatewayAdapter(type: GatewayAdapterType, logger: ILogger): IGatewayAdapter<Context>;
7
7
  export type HttpAdapterSetup = {
8
8
  adapter: IHttpAdapter;
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/graphql/gateway/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAC1C,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC;AAExC,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,OAAO,GACd,eAAe,CAAC,OAAO,CAAC,CAK1B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,gBAAgB,CAKzE"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../../src/graphql/gateway/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAK3C,OAAO,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,WAAW,CAAC;AACxD,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,CAAC;AAEpD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,kBAAkB,EACxB,MAAM,EAAE,OAAO,GACd,eAAe,CAAC,OAAO,CAAC,CAO1B;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,eAAe,GAAG,gBAAgB,CAOzE"}
@@ -1,15 +1,21 @@
1
1
  import { ApolloGatewayAdapter } from "./adapter-gateway-apollo.js";
2
+ import { MercuriusGatewayAdapter } from "./adapter-gateway-mercurius.js";
2
3
  import { createExpressHttpAdapter } from "./adapter-http-express.js";
4
+ import { createFastifyHttpAdapter } from "./adapter-http-fastify.js";
3
5
  export function createGatewayAdapter(type, logger) {
4
6
  switch (type) {
5
7
  case "apollo":
6
8
  return new ApolloGatewayAdapter(logger);
9
+ case "mercurius":
10
+ return new MercuriusGatewayAdapter(logger);
7
11
  }
8
12
  }
9
13
  export function createHttpAdapter(type) {
10
14
  switch (type) {
11
15
  case "express":
12
16
  return createExpressHttpAdapter();
17
+ case "fastify":
18
+ return createFastifyHttpAdapter();
13
19
  }
14
20
  }
15
21
  //# sourceMappingURL=factory.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../src/graphql/gateway/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAMrE,MAAM,UAAU,oBAAoB,CAClC,IAAwB,EACxB,MAAe;IAEf,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,wBAAwB,EAAE,CAAC;IACtC,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../../src/graphql/gateway/factory.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAMrE,MAAM,UAAU,oBAAoB,CAClC,IAAwB,EACxB,MAAe;IAEf,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ;YACX,OAAO,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC1C,KAAK,WAAW;YACd,OAAO,IAAI,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC;AAMD,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,SAAS;YACZ,OAAO,wBAAwB,EAAE,CAAC;QACpC,KAAK,SAAS;YACZ,OAAO,wBAAwB,EAAE,CAAC;IACtC,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter-gateway-mercurius.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-gateway-mercurius.test.d.ts","sourceRoot":"","sources":["../../../test/gateway/adapter-gateway-mercurius.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import { vi } from "vitest";
2
+ import { MercuriusGatewayAdapter } from "../../src/graphql/gateway/adapter-gateway-mercurius.js";
3
+ import { runGatewayAdapterContractTests, } from "./gateway-adapter-contract.js";
4
+ // ─── helpers ─────────────────────────────────────────────────────────────────
5
+ const silentLogger = {
6
+ level: "error",
7
+ verbose: vi.fn(),
8
+ debug: vi.fn(),
9
+ info: vi.fn(),
10
+ warn: vi.fn(),
11
+ error: vi.fn(),
12
+ errorHandler: vi.fn(),
13
+ child: () => silentLogger,
14
+ };
15
+ // ─── run the shared contract suite against MercuriusGatewayAdapter ───────────
16
+ runGatewayAdapterContractTests("MercuriusGatewayAdapter", async () => {
17
+ const adapter = new MercuriusGatewayAdapter(silentLogger);
18
+ return {
19
+ adapter,
20
+ close: () => adapter.stop(),
21
+ };
22
+ });
23
+ //# sourceMappingURL=adapter-gateway-mercurius.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-gateway-mercurius.test.js","sourceRoot":"","sources":["../../../test/gateway/adapter-gateway-mercurius.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,uBAAuB,EAAE,MAAM,wDAAwD,CAAC;AACjG,OAAO,EACL,8BAA8B,GAE/B,MAAM,+BAA+B,CAAC;AAEvC,gFAAgF;AAEhF,MAAM,YAAY,GAAG;IACnB,KAAK,EAAE,OAAgB;IACvB,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;IAChB,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;IACb,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE;IACd,YAAY,EAAE,EAAE,CAAC,EAAE,EAAE;IACrB,KAAK,EAAE,GAAG,EAAE,CAAC,YAAY;CAC1B,CAAC;AAEF,gFAAgF;AAEhF,8BAA8B,CAC5B,yBAAyB,EACzB,KAAK,IAAoC,EAAE;IACzC,MAAM,OAAO,GAAG,IAAI,uBAAuB,CAAC,YAAY,CAAC,CAAC;IAC1D,OAAO;QACL,OAAO;QACP,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;KAC5B,CAAC;AACJ,CAAC,CACF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapter-http-fastify.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-http-fastify.test.d.ts","sourceRoot":"","sources":["../../../test/gateway/adapter-http-fastify.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,17 @@
1
+ import { FastifyHttpAdapter } from "../../src/graphql/gateway/adapter-http-fastify.js";
2
+ import { runHttpAdapterContractTests, } from "./http-adapter-contract.js";
3
+ // ─── Fastify harness factory ──────────────────────────────────────────────────
4
+ async function createFastifyHarness() {
5
+ const adapter = new FastifyHttpAdapter();
6
+ adapter.setupMiddleware({});
7
+ const httpServer = await adapter.listen(0);
8
+ const addr = httpServer.address();
9
+ return {
10
+ adapter,
11
+ url: `http://127.0.0.1:${addr.port}`,
12
+ close: () => new Promise((resolve, reject) => httpServer.close((err) => (err ? reject(err) : resolve()))),
13
+ };
14
+ }
15
+ // ─── run the shared contract suite against FastifyHttpAdapter ─────────────────
16
+ runHttpAdapterContractTests("FastifyHttpAdapter", createFastifyHarness);
17
+ //# sourceMappingURL=adapter-http-fastify.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-http-fastify.test.js","sourceRoot":"","sources":["../../../test/gateway/adapter-http-fastify.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mDAAmD,CAAC;AACvF,OAAO,EACL,2BAA2B,GAE5B,MAAM,4BAA4B,CAAC;AAEpC,iFAAiF;AAEjF,KAAK,UAAU,oBAAoB;IACjC,MAAM,OAAO,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACzC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAE5B,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,EAAsB,CAAC;IAEtD,OAAO;QACL,OAAO;QACP,GAAG,EAAE,oBAAoB,IAAI,CAAC,IAAI,EAAE;QACpC,KAAK,EAAE,GAAG,EAAE,CACV,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACpC,UAAU,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAC3D;KACJ,CAAC;AACJ,CAAC;AAED,iFAAiF;AAEjF,2BAA2B,CAAC,oBAAoB,EAAE,oBAAoB,CAAC,CAAC"}