UNPKG

@graphql-hive/nestjs

Version:
1,010 lines (975 loc) • 29.6 kB
import { createLoggerFromLogging, PubSub, getCacheInstanceFromConfig, getBuiltinPluginsFromConfig, createGatewayRuntime, getGraphQLWSOptions } from '@graphql-hive/gateway'; import { asArray } from '@graphql-tools/utils'; import { Injectable, Logger as Logger$1 } from '@nestjs/common'; import { AbstractGraphQLDriver, GqlSubscriptionService } from '@nestjs/graphql'; import { handleMaybePromise } from '@whatwg-node/promise-helpers'; import { lexicographicSortSchema } from 'graphql'; const DisposableSymbols = { get asyncDispose() { return Symbol.asyncDispose || Symbol.for('asyncDispose'); }, }; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var fastSafeStringify = stringify; stringify.default = stringify; stringify.stable = deterministicStringify; stringify.stableStringify = deterministicStringify; var LIMIT_REPLACE_NODE = '[...]'; var CIRCULAR_REPLACE_NODE = '[Circular]'; var arr = []; var replacerStack = []; function defaultOptions () { return { depthLimit: Number.MAX_SAFE_INTEGER, edgesLimit: Number.MAX_SAFE_INTEGER } } // Regular stringify function stringify (obj, replacer, spacer, options) { if (typeof options === 'undefined') { options = defaultOptions(); } decirc(obj, '', 0, [], undefined, 0, options); var res; try { if (replacerStack.length === 0) { res = JSON.stringify(obj, replacer, spacer); } else { res = JSON.stringify(obj, replaceGetterValues(replacer), spacer); } } catch (_) { return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]') } finally { while (arr.length !== 0) { var part = arr.pop(); if (part.length === 4) { Object.defineProperty(part[0], part[1], part[3]); } else { part[0][part[1]] = part[2]; } } } return res } function setReplace (replace, val, k, parent) { var propertyDescriptor = Object.getOwnPropertyDescriptor(parent, k); if (propertyDescriptor.get !== undefined) { if (propertyDescriptor.configurable) { Object.defineProperty(parent, k, { value: replace }); arr.push([parent, k, val, propertyDescriptor]); } else { replacerStack.push([val, k, replace]); } } else { parent[k] = replace; arr.push([parent, k, val]); } } function decirc (val, k, edgeIndex, stack, parent, depth, options) { depth += 1; var i; if (typeof val === 'object' && val !== null) { for (i = 0; i < stack.length; i++) { if (stack[i] === val) { setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); return } } if ( typeof options.depthLimit !== 'undefined' && depth > options.depthLimit ) { setReplace(LIMIT_REPLACE_NODE, val, k, parent); return } if ( typeof options.edgesLimit !== 'undefined' && edgeIndex + 1 > options.edgesLimit ) { setReplace(LIMIT_REPLACE_NODE, val, k, parent); return } stack.push(val); // Optimize for Arrays. Big arrays could kill the performance otherwise! if (Array.isArray(val)) { for (i = 0; i < val.length; i++) { decirc(val[i], i, i, stack, val, depth, options); } } else { var keys = Object.keys(val); for (i = 0; i < keys.length; i++) { var key = keys[i]; decirc(val[key], key, i, stack, val, depth, options); } } stack.pop(); } } // Stable-stringify function compareFunction (a, b) { if (a < b) { return -1 } if (a > b) { return 1 } return 0 } function deterministicStringify (obj, replacer, spacer, options) { if (typeof options === 'undefined') { options = defaultOptions(); } var tmp = deterministicDecirc(obj, '', 0, [], undefined, 0, options) || obj; var res; try { if (replacerStack.length === 0) { res = JSON.stringify(tmp, replacer, spacer); } else { res = JSON.stringify(tmp, replaceGetterValues(replacer), spacer); } } catch (_) { return JSON.stringify('[unable to serialize, circular reference is too complex to analyze]') } finally { // Ensure that we restore the object as it was. while (arr.length !== 0) { var part = arr.pop(); if (part.length === 4) { Object.defineProperty(part[0], part[1], part[3]); } else { part[0][part[1]] = part[2]; } } } return res } function deterministicDecirc (val, k, edgeIndex, stack, parent, depth, options) { depth += 1; var i; if (typeof val === 'object' && val !== null) { for (i = 0; i < stack.length; i++) { if (stack[i] === val) { setReplace(CIRCULAR_REPLACE_NODE, val, k, parent); return } } try { if (typeof val.toJSON === 'function') { return } } catch (_) { return } if ( typeof options.depthLimit !== 'undefined' && depth > options.depthLimit ) { setReplace(LIMIT_REPLACE_NODE, val, k, parent); return } if ( typeof options.edgesLimit !== 'undefined' && edgeIndex + 1 > options.edgesLimit ) { setReplace(LIMIT_REPLACE_NODE, val, k, parent); return } stack.push(val); // Optimize for Arrays. Big arrays could kill the performance otherwise! if (Array.isArray(val)) { for (i = 0; i < val.length; i++) { deterministicDecirc(val[i], i, i, stack, val, depth, options); } } else { // Create a temporary object in the required way var tmp = {}; var keys = Object.keys(val).sort(compareFunction); for (i = 0; i < keys.length; i++) { var key = keys[i]; deterministicDecirc(val[key], key, i, stack, val, depth, options); tmp[key] = val[key]; } if (typeof parent !== 'undefined') { arr.push([parent, k, val]); parent[k] = tmp; } else { return tmp } } stack.pop(); } } // wraps replacer function to handle values we couldn't replace // and mark them as replaced value function replaceGetterValues (replacer) { replacer = typeof replacer !== 'undefined' ? replacer : function (k, v) { return v }; return function (key, val) { if (replacerStack.length > 0) { for (var i = 0; i < replacerStack.length; i++) { var part = replacerStack[i]; if (part[1] === key && part[0] === val) { val = part[2]; replacerStack.splice(i, 1); break } } } return replacer.call(this, key, val) } } var fastSafeStringify$1 = /*@__PURE__*/getDefaultExportFromCjs(fastSafeStringify); function tryStringify (o) { try { return JSON.stringify(o) } catch(e) { return '"[Circular]"' } } var quickFormatUnescaped = format; function format(f, args, opts) { var ss = (opts && opts.stringify) || tryStringify; var offset = 1; if (typeof f === 'object' && f !== null) { var len = args.length + offset; if (len === 1) return f var objects = new Array(len); objects[0] = ss(f); for (var index = 1; index < len; index++) { objects[index] = ss(args[index]); } return objects.join(' ') } if (typeof f !== 'string') { return f } var argLen = args.length; if (argLen === 0) return f var str = ''; var a = 1 - offset; var lastPos = -1; var flen = (f && f.length) || 0; for (var i = 0; i < flen;) { if (f.charCodeAt(i) === 37 && i + 1 < flen) { lastPos = lastPos > -1 ? lastPos : 0; switch (f.charCodeAt(i + 1)) { case 100: // 'd' case 102: // 'f' if (a >= argLen) break if (args[a] == null) break if (lastPos < i) str += f.slice(lastPos, i); str += Number(args[a]); lastPos = i + 2; i++; break case 105: // 'i' if (a >= argLen) break if (args[a] == null) break if (lastPos < i) str += f.slice(lastPos, i); str += Math.floor(Number(args[a])); lastPos = i + 2; i++; break case 79: // 'O' case 111: // 'o' case 106: // 'j' if (a >= argLen) break if (args[a] === undefined) break if (lastPos < i) str += f.slice(lastPos, i); var type = typeof args[a]; if (type === 'string') { str += '\'' + args[a] + '\''; lastPos = i + 2; i++; break } if (type === 'function') { str += args[a].name || '<anonymous>'; lastPos = i + 2; i++; break } str += ss(args[a]); lastPos = i + 2; i++; break case 115: // 's' if (a >= argLen) break if (lastPos < i) str += f.slice(lastPos, i); str += String(args[a]); lastPos = i + 2; i++; break case 37: // '%' if (lastPos < i) str += f.slice(lastPos, i); str += '%'; lastPos = i + 2; i++; a--; break } ++a; } ++i; } if (lastPos === -1) return f else if (lastPos < flen) { str += f.slice(lastPos); } return str } var format$1 = /*@__PURE__*/getDefaultExportFromCjs(quickFormatUnescaped); const logLevel = { trace: 0, debug: 1, info: 2, warn: 3, error: 4 }; function shouldLog(setLevel, loggingLevel) { setLevel = typeof setLevel === "function" ? setLevel() : setLevel; return setLevel !== false && // logging is not disabled logLevel[setLevel] <= logLevel[loggingLevel]; } function logLevelToString(level) { switch (level) { case "trace": return "TRC"; case "debug": return "DBG"; case "info": return "INF"; case "warn": return "WRN"; case "error": return "ERR"; default: throw new Error(`Unknown log level "${level}"`); } } function isPromise(val) { const obj = Object(val); return typeof obj.then === "function" && typeof obj.catch === "function" && typeof obj.finally === "function"; } function parseAttrs(attrs, functionUnwrapDepth = 0) { if (functionUnwrapDepth > 3) { throw new Error("Too much recursion while unwrapping function attributes"); } if (!attrs) { return void 0; } if (typeof attrs === "function") { return parseAttrs(attrs(), functionUnwrapDepth + 1); } if (Array.isArray(attrs)) { return attrs.map((val) => unwrapAttrVal(val)); } if (isPlainObject(attrs)) { const unwrapped = {}; for (const key of Object.keys(attrs)) { const val = attrs[key]; unwrapped[key] = unwrapAttrVal(val); } return unwrapped; } return objectifyClass(attrs); } function unwrapAttrVal(attr, visited = /* @__PURE__ */ new WeakSet()) { if (!attr) { return attr; } if (isPrimitive(attr)) { return attr; } if (typeof attr === "function") { return `[Function: ${attr.name || "(anonymous)"}]`; } if (visited.has(attr)) { return "[Circular]"; } visited.add(attr); if (Array.isArray(attr)) { return attr.map((val) => unwrapAttrVal(val)); } if (isPlainObject(attr)) { const unwrapped = {}; for (const key of Object.keys(attr)) { const val = attr[key]; unwrapped[key] = unwrapAttrVal(val, visited); } return unwrapped; } return objectifyClass(attr); } function isPrimitive(val) { return val !== Object(val); } const nodejsCustomInspectSy = Symbol.for("nodejs.util.inspect.custom"); function objectifyClass(val) { if ( // simply empty !val || // Object.create(null) Object(val).__proto__ == null ) { return {}; } if (typeof val === "object" && "toJSON" in val && typeof val.toJSON === "function") { return val.toJSON(); } if (typeof val === "object" && nodejsCustomInspectSy in val && typeof val[nodejsCustomInspectSy] === "function") { return { [nodejsCustomInspectSy.toString()]: unwrapAttrVal( val[nodejsCustomInspectSy](Infinity, {}) ), class: val.constructor.name }; } const props = {}; for (const propName of Object.getOwnPropertyNames(val)) { props[propName] = unwrapAttrVal(val[propName]); } for (const protoPropName of Object.getOwnPropertyNames( Object.getPrototypeOf(val) )) { const propVal = val[protoPropName]; if (typeof propVal === "function") { continue; } props[protoPropName] = unwrapAttrVal(propVal); } return { ...props, class: val.constructor.name }; } function getEnv(key) { return globalThis.process?.env?.[key] || // @ts-expect-error can exist in wrangler and maybe other runtimes globalThis.env?.[key] || // @ts-expect-error can exist in deno globalThis.Deno?.env?.get(key) || // @ts-expect-error could be globalThis[key]; } function truthyEnv(key) { return ["1", "t", "true", "y", "yes"].includes( getEnv(key)?.toLowerCase() || "" ); } function shallowMergeAttributes(target, source) { switch (true) { case (Array.isArray(source) && Array.isArray(target)): return [...target, ...source]; case Array.isArray(source): return target ? [target, ...source] : source; case Array.isArray(target): return source ? [...target, source] : target; case !!(target || source): return { ...target, ...source }; default: return void 0; } } function isPlainObject(val) { return Object(val).constructor === Object && Object.getPrototypeOf(val) === Object.prototype; } function jsonStringify(val, pretty) { return fastSafeStringify$1(val, void 0, pretty ? 2 : void 0); } const asciMap = { timestamp: "\x1B[90m", // bright black trace: "\x1B[36m", // cyan debug: "\x1B[90m", // bright black info: "\x1B[32m", // green warn: "\x1B[33m", // yellow error: "\x1B[41;39m", // red; white message: "\x1B[1m", // bold key: "\x1B[35m", // magenta reset: "\x1B[0m" // reset }; class ConsoleLogWriter { #console; #noColor; #noTimestamp; constructor(opts = {}) { const { console = globalThis.console, // no color if we're running in browser-like (edge) environments noColor = typeof process === "undefined" || // or no color if https://no-color.org/ truthyEnv("NO_COLOR"), noTimestamp = false } = opts; this.#console = console; this.#noColor = noColor; this.#noTimestamp = noTimestamp; } color(style, text) { if (!text) { return text; } if (this.#noColor) { return text; } return asciMap[style] + text + asciMap.reset; } write(level, attrs, msg) { this.#console[level === "trace" ? "debug" : level]( [ !this.#noTimestamp && this.color("timestamp", (/* @__PURE__ */ new Date()).toISOString()), this.color(level, logLevelToString(level)), this.color("message", msg), attrs && this.stringifyAttrs(attrs) ].filter(Boolean).join(" ") ); } stringifyAttrs(attrs) { let log = "\n"; for (const line of jsonStringify(attrs, true).split("\n")) { if (line === "{" || line === "}" || line === "[" || line === "]") { continue; } let formattedLine = line; formattedLine = formattedLine.replace( /"([^"]+)":/, this.color("key", "$1:") ); let indentationSize = line.match(/^\s*/)?.[0]?.length || 0; if (indentationSize) indentationSize++; formattedLine = formattedLine.replaceAll( /\\n/g, "\n" + [...Array(indentationSize)].join(" ") ); formattedLine = formattedLine.replace(/,$/, ""); formattedLine = formattedLine.replace( /(\[|\{|\]|\})$/, this.color("key", "$1") ); log += formattedLine + "\n"; } log = log.slice(0, -1); return log; } } class JSONLogWriter { write(level, attrs, msg) { console.log( jsonStringify( { ...attrs, level, ...msg ? { msg } : {}, timestamp: (/* @__PURE__ */ new Date()).toISOString() }, truthyEnv("LOG_JSON_PRETTY") ) ); } } class Logger { #level; #prefix; #attrs; #writers; #pendingWrites; constructor(opts = {}) { let logLevelEnv = getEnv("LOG_LEVEL"); if (logLevelEnv && !(logLevelEnv in logLevel)) { throw new Error( `Invalid LOG_LEVEL environment variable "${logLevelEnv}". Must be one of: ${[...Object.keys(logLevel), "false"].join(", ")}` ); } this.#level = opts.level ?? logLevelEnv ?? (truthyEnv("DEBUG") ? "debug" : "info"); this.#prefix = opts.prefix; this.#attrs = opts.attrs; this.#writers = opts.writers ?? (truthyEnv("LOG_JSON") ? [new JSONLogWriter()] : [new ConsoleLogWriter()]); } /** The prefix that's prepended to each log message. */ get prefix() { return this.#prefix; } /** * The attributes that are added to each log. If the log itself contains * attributes with keys existing in {@link attrs}, the log's attributes will * override. */ get attrs() { return this.#attrs; } /** The current {@link LogLevel} of the logger. You can change the level using the {@link setLevel} method. */ get level() { return typeof this.#level === "function" ? this.#level() : this.#level; } /** * Sets the new {@link LogLevel} of the logger. All subsequent logs, and {@link child child loggers} whose * level did not change, will respect the new level. */ setLevel(level) { this.#level = level; } write(level, attrs, msg) { for (const w of this.#writers) { const write$ = w.write(level, attrs, msg); if (isPromise(write$)) { this.#pendingWrites ??= /* @__PURE__ */ new Set(); this.#pendingWrites.add(write$); write$.then(() => { this.#pendingWrites.delete(write$); }).catch((e) => { console.error("Failed to write async log", e); }); } } } flush() { if (this.#pendingWrites?.size) { const errs = []; return Promise.allSettled( Array.from(this.#pendingWrites).map( (w) => w.catch((err) => errs.push(err)) ) ).then(() => { this.#pendingWrites.clear(); if (errs.length) { throw new AggregateError( errs, `Failed to flush ${errs.length} writes` ); } }); } return; } async [DisposableSymbols.asyncDispose]() { return this.flush(); } child(prefixOrAttrs, prefix) { if (typeof prefixOrAttrs === "string") { return new Logger({ level: () => this.level, // inherits the parent level (yet can be changed on child only when using setLevel) prefix: (this.#prefix || "") + prefixOrAttrs, attrs: this.#attrs, writers: this.#writers }); } return new Logger({ level: () => this.level, // inherits the parent level (yet can be changed on child only when using setLevel) prefix: (this.#prefix || "") + (prefix || "") || void 0, attrs: shallowMergeAttributes(this.#attrs, prefixOrAttrs), writers: this.#writers }); } log(level, maybeAttrsOrMsg, ...rest) { if (!shouldLog(this.#level, level)) { return; } let msg; let attrs; if (typeof maybeAttrsOrMsg === "string") { msg = maybeAttrsOrMsg; } else if (maybeAttrsOrMsg) { attrs = maybeAttrsOrMsg; if (typeof rest[0] === "string") { msg = rest.shift(); } } if (this.#prefix) { msg = `${this.#prefix}${msg || ""}`.trim(); } attrs = shallowMergeAttributes(parseAttrs(this.#attrs), parseAttrs(attrs)); msg = msg && rest.length ? format$1(msg, rest, { stringify: fastSafeStringify$1 }) : msg; this.write(level, attrs, msg); if (truthyEnv("LOG_TRACE_LOGS")) { console.trace("\u{1F446}"); } } trace(...args) { this.log( "trace", ...args ); } debug(...args) { this.log( "debug", ...args ); } info(...args) { this.log( "info", ...args ); } warn(...args) { this.log( "warn", ...args ); } error(...args) { this.log( "error", ...args ); } } var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __knownSymbol = (name, symbol) => (symbol = Symbol[name]) ? symbol : Symbol.for("Symbol." + name); var __typeError = (msg) => { throw TypeError(msg); }; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __decoratorStart = (base) => [, , , __create(base?.[__knownSymbol("metadata")] ?? null)]; var __decoratorStrings = ["class", "method", "getter", "setter", "accessor", "field", "value", "get", "set"]; var __expectFn = (fn) => fn !== void 0 && typeof fn !== "function" ? __typeError("Function expected") : fn; var __decoratorContext = (kind, name, done, metadata, fns) => ({ kind: __decoratorStrings[kind], name, metadata, addInitializer: (fn) => done._ ? __typeError("Already initialized") : fns.push(__expectFn(fn || null)) }); var __decoratorMetadata = (array, target) => __defNormalProp(target, __knownSymbol("metadata"), array[3]); var __runInitializers = (array, flags, self, value) => { for (var i = 0, fns = array[flags >> 1], n = fns && fns.length; i < n; i++) fns[i].call(self) ; return value; }; var __decorateElement = (array, flags, name, decorators, target, extra) => { var it, done, ctx, k = flags & 7, p = false; var j = 0; var extraInitializers = array[j] || (array[j] = []); var desc = k && ((target = target.prototype), k < 5 && (k > 3 || !p) && __getOwnPropDesc(target , name)); __name(target, name); for (var i = decorators.length - 1; i >= 0; i--) { ctx = __decoratorContext(k, name, done = {}, array[3], extraInitializers); it = (0, decorators[i])(target, ctx), done._ = 1; __expectFn(it) && (target = it); } return __decoratorMetadata(array, target), desc && __defProp(target, name, desc), p ? k ^ 4 ? extra : desc : target; }; var _HiveGatewayDriver_decorators, _init, _a; _HiveGatewayDriver_decorators = [Injectable()]; class HiveGatewayDriver extends (_a = AbstractGraphQLDriver) { _gatewayRuntime; _subscriptionService; async ensureGatewayRuntime({ typeDefs, resolvers, logging, ...options }) { if (this._gatewayRuntime) { return this._gatewayRuntime; } const additionalTypeDefs = []; if (typeDefs) { additionalTypeDefs.push(typeDefs); } const additionalResolvers = []; if (resolvers) { additionalResolvers.push(...asArray(resolvers)); } let log; if (logging != null) { log = createLoggerFromLogging(logging); } else { const nestLog = new Logger$1("Hive Gateway"); log = new Logger({ writers: [ { write(level, attrs, msg) { switch (level) { case "trace": nestLog.verbose(msg, attrs); break; case "info": nestLog.log(msg, attrs); break; default: nestLog[level](msg, attrs); } } } ] }); } const configCtx = { log, cwd: process.cwd(), pubsub: options.pubsub || new PubSub() }; const cache = await getCacheInstanceFromConfig(options, configCtx); const builtinPlugins = await getBuiltinPluginsFromConfig(options, { ...configCtx, cache }); this._gatewayRuntime = createGatewayRuntime({ ...options, logging: configCtx.log, cache, graphqlEndpoint: options.path, additionalTypeDefs, additionalResolvers, disableIntrospection: options.introspection === false ? { disableIf: () => options.introspection || false } : void 0, ...options.context || options.transformSchema || options.sortSchema ? { plugins: (ctx) => { const existingPlugins = options.plugins?.(ctx) || []; if (options.context) { const contextPlugin = { onContextBuilding: ({ context, extendContext }) => handleMaybePromise( () => typeof options.context === "function" ? options.context(context) : options.context, extendContext ) }; existingPlugins.push(contextPlugin); } if (options.transformSchema) { const schemaTransformPlugin = { onSchemaChange({ schema, replaceSchema }) { return handleMaybePromise( () => options.transformSchema(schema), replaceSchema ); } }; existingPlugins.push(schemaTransformPlugin); } if (options.sortSchema) { const schemaSortPlugin = { onSchemaChange({ schema, replaceSchema }) { replaceSchema(lexicographicSortSchema(schema)); } }; existingPlugins.push(schemaSortPlugin); } return [...builtinPlugins, ...existingPlugins]; } } : {} }); return this._gatewayRuntime; } async start(options) { const gatewayRuntime = await this.ensureGatewayRuntime(options); const platformName = this.httpAdapterHost.httpAdapter.getType(); if (platformName === "express") { this.registerExpress(); } else if (platformName === "fastify") { this.registerFastify(); } else { throw new Error(`No support for current HttpAdapter: ${platformName}`); } if (options.installSubscriptionHandlers || options.subscriptions) { const subscriptionsOptions = options.subscriptions || { "graphql-ws": {} }; if (subscriptionsOptions["graphql-ws"]) { const gwOptions = getGraphQLWSOptions( gatewayRuntime, (ctx) => ({ req: ctx.extra?.request, socket: ctx.extra?.socket }) ); subscriptionsOptions["graphql-ws"] = { ...gwOptions, ...typeof subscriptionsOptions["graphql-ws"] === "object" ? subscriptionsOptions["graphql-ws"] : {} }; } if (subscriptionsOptions["subscriptions-transport-ws"]) { subscriptionsOptions["subscriptions-transport-ws"] = typeof subscriptionsOptions["subscriptions-transport-ws"] === "object" ? subscriptionsOptions["subscriptions-transport-ws"] : {}; subscriptionsOptions["subscriptions-transport-ws"].onOperation = async (_msg, params, ws) => { const { schema, execute, subscribe, contextFactory, parse, validate } = gatewayRuntime.getEnveloped({ ...params.context, req: ( // @ts-expect-error upgradeReq does exist but is untyped ws.upgradeReq ), socket: ws, params }); const args = { schema, operationName: params.operationName, document: typeof params.query === "string" ? parse(params.query) : params.query, variables: params.variables, context: await contextFactory(), rootValue: { execute, subscribe } }; const errors = validate(args.schema, args.document); if (errors.length) return errors; return args; }; } this._subscriptionService = new GqlSubscriptionService( { schema: await gatewayRuntime.getSchema(), path: options.path, // @ts-expect-error - We know that execute and subscribe are defined execute: (args) => args.rootValue.execute(args), // @ts-expect-error - We know that execute and subscribe are defined subscribe: (args) => args.rootValue.subscribe(args), ...subscriptionsOptions }, this.httpAdapterHost.httpAdapter?.getHttpServer() ); } } async stop() { await Promise.all([ this._subscriptionService?.stop(), this._gatewayRuntime?.dispose() ]); } async generateSchema(options) { const gatewayRuntime = await this.ensureGatewayRuntime(options); return gatewayRuntime.getSchema(); } registerExpress() { if (!this._gatewayRuntime) { throw new Error("Hive Gateway is not initialized"); } this.httpAdapterHost.httpAdapter.use(this._gatewayRuntime); } registerFastify() { this.httpAdapterHost.httpAdapter.getInstance().all("*", async (req, reply) => { if (!this._gatewayRuntime) { throw new Error("Hive Gateway is not initialized"); } const response = await this._gatewayRuntime.handleNodeRequestAndResponse(req, reply, { req, reply }); response.headers.forEach((value, key) => { reply.header(key, value); }); reply.status(response.status); reply.send(response.body); return reply; }); } } _init = __decoratorStart(_a); HiveGatewayDriver = __decorateElement(_init, 0, "HiveGatewayDriver", _HiveGatewayDriver_decorators, HiveGatewayDriver); __runInitializers(_init, 1, HiveGatewayDriver); export { HiveGatewayDriver };