UNPKG

@apollo/gateway

Version:
620 lines 32.7 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __exportStar = (this && this.__exportStar) || function(m, exports) { for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.UplinkFetcherError = exports.UplinkSupergraphManager = exports.LocalCompose = exports.IntrospectAndCompose = exports.buildOperationContext = exports.executeQueryPlan = exports.ApolloGateway = exports.SERVICE_DEFINITION_QUERY = exports.HEALTH_CHECK_QUERY = void 0; const util_1 = require("util"); const utils_createhash_1 = require("@apollo/utils.createhash"); const utils_keyvaluecache_1 = require("@apollo/utils.keyvaluecache"); const operationContext_1 = require("./operationContext"); Object.defineProperty(exports, "buildOperationContext", { enumerable: true, get: function () { return operationContext_1.buildOperationContext; } }); const executeQueryPlan_1 = require("./executeQueryPlan"); Object.defineProperty(exports, "executeQueryPlan", { enumerable: true, get: function () { return executeQueryPlan_1.executeQueryPlan; } }); const types_1 = require("./datasources/types"); const RemoteGraphQLDataSource_1 = require("./datasources/RemoteGraphQLDataSource"); const values_1 = require("graphql/execution/values"); const query_planner_1 = require("@apollo/query-planner"); const config_1 = require("./config"); const api_1 = require("@opentelemetry/api"); const opentelemetry_1 = require("./utilities/opentelemetry"); const addExtensions_1 = require("./schema-helper/addExtensions"); const supergraphManagers_1 = require("./supergraphManagers"); Object.defineProperty(exports, "IntrospectAndCompose", { enumerable: true, get: function () { return supergraphManagers_1.IntrospectAndCompose; } }); Object.defineProperty(exports, "UplinkSupergraphManager", { enumerable: true, get: function () { return supergraphManagers_1.UplinkSupergraphManager; } }); Object.defineProperty(exports, "LocalCompose", { enumerable: true, get: function () { return supergraphManagers_1.LocalCompose; } }); const federation_internals_1 = require("@apollo/federation-internals"); const logger_1 = require("./logger"); exports.HEALTH_CHECK_QUERY = 'query __ApolloServiceHealthCheck__ { __typename }'; exports.SERVICE_DEFINITION_QUERY = 'query __ApolloGetServiceDefinition__ { _service { sdl } }'; class ApolloGateway { constructor(config) { var _a, _b, _c; this.serviceMap = Object.create(null); this.onSchemaChangeListeners = new Set(); this.onSchemaLoadOrUpdateListeners = new Set(); this.warnedStates = Object.create(null); this.toDispose = []; this.executor = async (requestContext) => { return opentelemetry_1.tracer.startActiveSpan(opentelemetry_1.OpenTelemetrySpanNames.REQUEST, { attributes: (0, opentelemetry_1.requestContextSpanAttributes)(requestContext, this.config.telemetry) }, async (span) => { try { const { request, document, queryHash } = requestContext; const queryPlanStoreKey = request.operationName ? (0, utils_createhash_1.createHash)('sha256').update(queryHash).update(request.operationName).digest('hex') : queryHash; const operationContext = (0, operationContext_1.buildOperationContext)({ schema: this.schema, operationDocument: document, operationName: request.operationName, }); span.setAttributes((0, opentelemetry_1.operationContextSpanAttributes)(operationContext)); const validationErrors = this.validateIncomingRequest(requestContext, operationContext); if (validationErrors.length > 0) { (0, opentelemetry_1.recordExceptions)(span, validationErrors, this.config.telemetry); span.setStatus({ code: api_1.SpanStatusCode.ERROR }); return { errors: validationErrors }; } let queryPlan = await this.queryPlanStore.get(queryPlanStoreKey); if (!queryPlan) { queryPlan = opentelemetry_1.tracer.startActiveSpan(opentelemetry_1.OpenTelemetrySpanNames.PLAN, requestContext.operationName ? { attributes: { [opentelemetry_1.OpenTelemetryAttributeNames.GRAPHQL_OPERATION_NAME]: requestContext.operationName, }, } : {}, (span) => { try { const operation = (0, federation_internals_1.operationFromDocument)(this.apiSchema, document, { operationName: request.operationName }); return this.queryPlanner.buildQueryPlan(operation, { recursiveSelectionsLimitDisabled: this.recursiveSelectionsLimitDisabled, nonLocalSelectionsLimitDisabled: this.nonLocalSelectionsLimitDisabled, }); } catch (err) { (0, opentelemetry_1.recordExceptions)(span, [err], this.config.telemetry); span.setStatus({ code: api_1.SpanStatusCode.ERROR }); throw err; } finally { span.end(); } }); try { await this.queryPlanStore.set(queryPlanStoreKey, queryPlan); } catch (err) { this.logger.warn('Could not store queryPlan' + ((err && err.message) || err)); } } const serviceMap = Object.entries(this.serviceMap).reduce((serviceDataSources, [serviceName, { dataSource }]) => { serviceDataSources[serviceName] = dataSource; return serviceDataSources; }, Object.create(null)); if (this.experimental_didResolveQueryPlan) { this.experimental_didResolveQueryPlan({ queryPlan, serviceMap, requestContext, operationContext, }); } const response = await (0, executeQueryPlan_1.executeQueryPlan)(queryPlan, serviceMap, requestContext, operationContext, this.supergraphSchema, this.apiSchema, this.config.telemetry); const shouldShowQueryPlan = this.config.__exposeQueryPlanExperimental && request.http && request.http.headers && request.http.headers.get('Apollo-Query-Plan-Experimental'); const serializedQueryPlan = queryPlan.node && (this.config.debug || shouldShowQueryPlan) ? (0, query_planner_1.prettyFormatQueryPlan)(queryPlan) : null; if (this.config.debug && serializedQueryPlan) { this.logger.debug(serializedQueryPlan); } if (shouldShowQueryPlan) { const queryPlanFormat = request.http && request.http.headers && request.http.headers.has('Apollo-Query-Plan-Experimental-Format') ? request.http.headers.get('Apollo-Query-Plan-Experimental-Format') : 'prettified'; response.extensions = { __queryPlanExperimental: queryPlanFormat === 'prettified' ? serializedQueryPlan || true : queryPlanFormat === 'internal' ? queryPlan : true }; } if (response.errors) { (0, opentelemetry_1.recordExceptions)(span, response.errors, this.config.telemetry); span.setStatus({ code: api_1.SpanStatusCode.ERROR }); } return response; } catch (err) { (0, opentelemetry_1.recordExceptions)(span, [err], this.config.telemetry); span.setStatus({ code: api_1.SpanStatusCode.ERROR }); throw err; } finally { span.end(); } }); }; this.config = { __exposeQueryPlanExperimental: process.env.NODE_ENV !== 'production', ...config, }; this.logger = (_a = this.config.logger) !== null && _a !== void 0 ? _a : (0, logger_1.getDefaultLogger)(this.config.debug); this.queryPlanStore = this.initQueryPlanStore(config === null || config === void 0 ? void 0 : config.experimental_approximateQueryPlanStoreMiB); this.experimental_didResolveQueryPlan = config === null || config === void 0 ? void 0 : config.experimental_didResolveQueryPlan; this.experimental_didUpdateSupergraph = config === null || config === void 0 ? void 0 : config.experimental_didUpdateSupergraph; this.recursiveSelectionsLimitDisabled = process.env.APOLLO_DISABLE_SECURITY_RECURSIVE_SELECTIONS_CHECK === 'true'; this.nonLocalSelectionsLimitDisabled = process.env.APOLLO_DISABLE_SECURITY_NON_LOCAL_SELECTIONS_CHECK === 'true'; if ((0, config_1.isManagedConfig)(this.config)) { this.pollIntervalInMs = (_b = this.config.fallbackPollIntervalInMs) !== null && _b !== void 0 ? _b : this.config.pollIntervalInMs; } else if ((0, config_1.isServiceListConfig)(this.config)) { this.pollIntervalInMs = (_c = this.config) === null || _c === void 0 ? void 0 : _c.pollIntervalInMs; } this.validateConfigAndEmitWarnings(); this.logger.debug('Gateway successfully initialized (but not yet loaded)'); this.state = { phase: 'initialized' }; } get supergraphManager() { return this._supergraphManager; } initQueryPlanStore(approximateQueryPlanStoreMiB) { var _a, _b, _c; if ((_a = this.config.queryPlannerConfig) === null || _a === void 0 ? void 0 : _a.cache) { return (_b = this.config.queryPlannerConfig) === null || _b === void 0 ? void 0 : _b.cache; } const defaultSize = ((_c = this.config.queryPlannerConfig) === null || _c === void 0 ? void 0 : _c.exposeDocumentNodeInFetchNode) ? 50 : 30; return new utils_keyvaluecache_1.InMemoryLRUCache({ maxSize: Math.pow(2, 20) * (approximateQueryPlanStoreMiB || defaultSize), sizeCalculation: approximateObjectSize, }); } validateConfigAndEmitWarnings() { var _a; (0, federation_internals_1.assert)(!((_a = this.config.queryPlannerConfig) === null || _a === void 0 ? void 0 : _a.typeConditionedFetching), "Type conditions are not supported in the gateway"); if (this.pollIntervalInMs && (0, config_1.isServiceListConfig)(this.config)) { this.logger.warn('Polling running services is dangerous and not recommended in production. ' + 'Polling should only be used against a registry. ' + 'If you are polling running services, use with caution.'); } if ((0, config_1.isManuallyManagedConfig)(this.config) && 'experimental_updateSupergraphSdl' in this.config && 'experimental_updateServiceDefinitions' in this.config) { this.logger.warn('Gateway found two manual update configurations when only one should be ' + 'provided. Gateway will default to using the provided `experimental_updateSupergraphSdl` ' + 'function when both `experimental_updateSupergraphSdl` and experimental_updateServiceDefinitions` ' + 'are provided.'); } if ('schemaConfigDeliveryEndpoint' in this.config) { this.logger.warn('The `schemaConfigDeliveryEndpoint` option is deprecated and will be removed in a future version of `@apollo/gateway`. Please migrate to the equivalent (array form) `uplinkEndpoints` configuration option.'); } if ((0, config_1.isManagedConfig)(this.config) && 'pollIntervalInMs' in this.config) { this.logger.warn('The `pollIntervalInMs` option is deprecated and will be removed in a future version of `@apollo/gateway`. ' + 'Please migrate to the equivalent `fallbackPollIntervalInMs` configuration option. ' + 'The poll interval is now defined by Uplink, this option will only be used if it is greater than the value defined by Uplink or as a fallback.'); } } async load(options) { var _a, _b, _c; this.logger.debug('Loading gateway...'); if (this.state.phase !== 'initialized') { throw Error(`ApolloGateway.load called in surprising state ${this.state.phase}`); } if (options === null || options === void 0 ? void 0 : options.apollo) { const { key, keyHash, graphRef, graphId, graphVariant } = options.apollo; this.apolloConfig = { key, keyHash, graphRef: graphRef !== null && graphRef !== void 0 ? graphRef : (graphId ? `${graphId}@${graphVariant !== null && graphVariant !== void 0 ? graphVariant : 'current'}` : undefined), }; } else if (options === null || options === void 0 ? void 0 : options.engine) { const { apiKeyHash, graphId, graphVariant } = options.engine; this.apolloConfig = { keyHash: apiKeyHash, graphRef: graphId ? `${graphId}@${graphVariant !== null && graphVariant !== void 0 ? graphVariant : 'current'}` : undefined, }; } this.maybeWarnOnConflictingConfig(); if ((0, config_1.isStaticSupergraphSdlConfig)(this.config)) { const supergraphSdl = this.config.supergraphSdl; await this.initializeSupergraphManager({ initialize: async () => { return { supergraphSdl, }; }, }); } else if ((0, config_1.isLocalConfig)(this.config)) { await this.initializeSupergraphManager(new supergraphManagers_1.LocalCompose({ localServiceList: this.config.localServiceList, logger: this.logger, })); } else if ((0, config_1.isManuallyManagedSupergraphSdlGatewayConfig)(this.config)) { const supergraphManager = typeof this.config.supergraphSdl === 'object' ? this.config.supergraphSdl : { initialize: this.config.supergraphSdl }; await this.initializeSupergraphManager(supergraphManager); } else if ('experimental_updateServiceDefinitions' in this.config || 'experimental_updateSupergraphSdl' in this.config) { const updateServiceDefinitions = 'experimental_updateServiceDefinitions' in this.config ? this.config.experimental_updateServiceDefinitions : this.config.experimental_updateSupergraphSdl; await this.initializeSupergraphManager(new supergraphManagers_1.LegacyFetcher({ logger: this.logger, gatewayConfig: this.config, updateServiceDefinitions, pollIntervalInMs: this.pollIntervalInMs, subgraphHealthCheck: this.config.serviceHealthCheck, })); } else if ((0, config_1.isServiceListConfig)(this.config)) { this.logger.warn('The `serviceList` option is deprecated and will be removed in a future version of `@apollo/gateway`. Please migrate to its replacement `IntrospectAndCompose`. More information on `IntrospectAndCompose` can be found in the documentation.'); await this.initializeSupergraphManager(new supergraphManagers_1.IntrospectAndCompose({ subgraphs: this.config.serviceList, pollIntervalInMs: this.pollIntervalInMs, logger: this.logger, subgraphHealthCheck: this.config.serviceHealthCheck, introspectionHeaders: this.config.introspectionHeaders, })); } else { const canUseManagedConfig = ((_a = this.apolloConfig) === null || _a === void 0 ? void 0 : _a.graphRef) && ((_b = this.apolloConfig) === null || _b === void 0 ? void 0 : _b.keyHash); if (!canUseManagedConfig) { throw new Error('When a manual configuration is not provided, gateway requires an Apollo ' + 'configuration. See https://www.apollographql.com/docs/apollo-server/federation/managed-federation/ ' + 'for more information. Manual configuration options include: ' + '`serviceList`, `supergraphSdl`, and `experimental_updateServiceDefinitions`.'); } const schemaDeliveryEndpoints = this.config .schemaConfigDeliveryEndpoint ? [this.config.schemaConfigDeliveryEndpoint] : undefined; await this.initializeSupergraphManager(new supergraphManagers_1.UplinkSupergraphManager({ graphRef: this.apolloConfig.graphRef, apiKey: this.apolloConfig.key, shouldRunSubgraphHealthcheck: this.config.serviceHealthCheck, uplinkEndpoints: (_c = this.config.uplinkEndpoints) !== null && _c !== void 0 ? _c : schemaDeliveryEndpoints, maxRetries: this.config.uplinkMaxRetries, fetcher: this.config.fetcher, logger: this.logger, fallbackPollIntervalInMs: this.pollIntervalInMs, })); } const mode = (0, config_1.isManagedConfig)(this.config) ? 'managed' : 'unmanaged'; this.logger.info(`Gateway successfully loaded schema.\n\t* Mode: ${mode}${this.apolloConfig && this.apolloConfig.graphRef ? `\n\t* Service: ${this.apolloConfig.graphRef}` : ''}`); (0, addExtensions_1.addExtensions)(this.schema); return { schema: this.schema, executor: this.executor, }; } getIdForSupergraphSdl(supergraphSdl) { return (0, utils_createhash_1.createHash)('sha256').update(supergraphSdl).digest('hex'); } async initializeSupergraphManager(supergraphManager) { try { const result = await supergraphManager.initialize({ update: this.externalSupergraphUpdateCallback.bind(this), healthCheck: this.externalSubgraphHealthCheckCallback.bind(this), getDataSource: this.externalGetDataSourceCallback.bind(this), }); if (result === null || result === void 0 ? void 0 : result.cleanup) { if (typeof result.cleanup === 'function') { this.toDispose.push(result.cleanup); } else { this.logger.error('Provided `supergraphSdl` function returned an invalid `cleanup` property (must be a function)'); } } this.externalSupergraphUpdateCallback(result.supergraphSdl); } catch (e) { this.state = { phase: 'failed to load' }; await this.performCleanupAndLogErrors(); throw e; } this._supergraphManager = supergraphManager; this.state = { phase: 'loaded' }; } externalSupergraphUpdateCallback(supergraphSdl) { switch (this.state.phase) { case 'failed to load': throw new Error("Can't call `update` callback after gateway failed to load."); case 'updating schema': throw new Error("Can't call `update` callback while supergraph update is in progress."); case 'stopped': throw new Error("Can't call `update` callback after gateway has been stopped."); case 'stopping': throw new Error("Can't call `update` callback while gateway is stopping."); case 'loaded': case 'initialized': break; default: throw new UnreachableCaseError(this.state); } this.state = { phase: 'updating schema' }; try { this.updateWithSupergraphSdl({ supergraphSdl, id: this.getIdForSupergraphSdl(supergraphSdl), }); } finally { this.state = { phase: 'loaded' }; } } async externalSubgraphHealthCheckCallback(supergraphSdl) { const serviceList = this.serviceListFromSupergraphSdl(supergraphSdl); const serviceMap = serviceList.reduce((serviceMap, serviceDef) => { serviceMap[serviceDef.name] = { url: serviceDef.url, dataSource: this.createDataSource(serviceDef), }; return serviceMap; }, Object.create(null)); try { await this.serviceHealthCheck(serviceMap); } catch (e) { throw new Error('The gateway subgraphs health check failed. Updating to the provided ' + '`supergraphSdl` will likely result in future request failures to ' + 'subgraphs. The following error occurred during the health check:\n' + e.message); } } externalGetDataSourceCallback({ name, url, }) { return this.getOrCreateDataSource({ name, url }); } updateWithSupergraphSdl(result) { if (result.id === this.compositionId) { this.logger.debug('No change in composition since last check.'); return; } const { supergraph, supergraphSdl } = this.createSchemaFromSupergraphSdl(result.supergraphSdl); const previousSchema = this.schema; const previousSupergraphSdl = this.supergraphSdl; const previousCompositionId = this.compositionId; if (previousSchema) { this.logger.info(`Updated Supergraph SDL was found [Composition ID ${this.compositionId} => ${result.id}]`); } this.compositionId = result.id; this.supergraphSdl = supergraphSdl; this.supergraphSchema = supergraph.schema.toGraphQLJSSchema(); if (!supergraphSdl) { this.logger.error("A valid schema couldn't be composed. Falling back to previous schema."); } else { this.updateWithSchemaAndNotify(supergraph, supergraphSdl); if (this.experimental_didUpdateSupergraph) { this.experimental_didUpdateSupergraph({ compositionId: result.id, supergraphSdl, schema: this.schema, }, previousCompositionId && previousSupergraphSdl && previousSchema ? { compositionId: previousCompositionId, supergraphSdl: previousSupergraphSdl, schema: previousSchema, } : undefined); } } } updateWithSchemaAndNotify(supergraph, supergraphSdl, legacyDontNotifyOnSchemaChangeListeners = false) { this.queryPlanStore.clear(); this.apiSchema = supergraph.apiSchema(); this.schema = (0, addExtensions_1.addExtensions)(this.apiSchema.toGraphQLJSSchema()); this.queryPlanner = new query_planner_1.QueryPlanner(supergraph, this.config.queryPlannerConfig); if (!legacyDontNotifyOnSchemaChangeListeners) { this.onSchemaChangeListeners.forEach((listener) => { try { listener(this.schema); } catch (e) { this.logger.error("An error was thrown from an 'onSchemaChange' listener. " + 'The schema will still update: ' + ((e && e.message) || e)); } }); } this.onSchemaLoadOrUpdateListeners.forEach((listener) => { try { listener({ apiSchema: this.schema, coreSupergraphSdl: supergraphSdl, }); } catch (e) { this.logger.error("An error was thrown from an 'onSchemaLoadOrUpdate' listener. " + 'The schema will still update: ' + ((e && e.message) || e)); } }); } serviceHealthCheck(serviceMap = this.serviceMap) { return Promise.all(Object.entries(serviceMap).map(([name, { dataSource }]) => dataSource .process({ kind: types_1.GraphQLDataSourceRequestKind.HEALTH_CHECK, request: { query: exports.HEALTH_CHECK_QUERY }, context: {}, }) .then((response) => ({ name, response })) .catch((e) => { throw new Error(`[${name}]: ${e.message}`); }))); } serviceListFromSupergraphSdl(supergraphSdl) { return federation_internals_1.Supergraph.build(supergraphSdl).subgraphsMetadata(); } createSchemaFromSupergraphSdl(supergraphSdl) { var _a; const validateSupergraph = (_a = this.config.validateSupergraph) !== null && _a !== void 0 ? _a : process.env.NODE_ENV !== 'production'; const supergraph = federation_internals_1.Supergraph.build(supergraphSdl, { validateSupergraph }); this.createServices(supergraph.subgraphsMetadata()); return { supergraph, supergraphSdl, }; } onSchemaChange(callback) { this.onSchemaChangeListeners.add(callback); return () => { this.onSchemaChangeListeners.delete(callback); }; } onSchemaLoadOrUpdate(callback) { this.onSchemaLoadOrUpdateListeners.add(callback); return () => { this.onSchemaLoadOrUpdateListeners.delete(callback); }; } getOrCreateDataSource(serviceDef) { if (this.serviceMap[serviceDef.name] && serviceDef.url === this.serviceMap[serviceDef.name].url) { return this.serviceMap[serviceDef.name].dataSource; } const dataSource = this.createDataSource(serviceDef); this.serviceMap[serviceDef.name] = { url: serviceDef.url, dataSource }; return dataSource; } createDataSource(serviceDef) { if (!serviceDef.url && !(0, config_1.isLocalConfig)(this.config)) { this.logger.error(`Service definition for service ${serviceDef.name} is missing a url`); } return this.config.buildService ? this.config.buildService(serviceDef) : new RemoteGraphQLDataSource_1.RemoteGraphQLDataSource({ url: serviceDef.url, }); } createServices(services) { for (const serviceDef of services) { this.getOrCreateDataSource(serviceDef); } } maybeWarnOnConflictingConfig() { var _a, _b; const canUseManagedConfig = ((_a = this.apolloConfig) === null || _a === void 0 ? void 0 : _a.graphRef) && ((_b = this.apolloConfig) === null || _b === void 0 ? void 0 : _b.keyHash); if (!(0, config_1.isManagedConfig)(this.config) && canUseManagedConfig && !this.warnedStates.remoteWithLocalConfig) { this.warnedStates.remoteWithLocalConfig = true; this.logger.warn('A local gateway configuration is overriding a managed federation ' + 'configuration. To use the managed ' + 'configuration, do not specify a service list or supergraphSdl locally.'); } } validateIncomingRequest(requestContext, operationContext) { return opentelemetry_1.tracer.startActiveSpan(opentelemetry_1.OpenTelemetrySpanNames.VALIDATE, (span) => { try { const variableDefinitions = operationContext.operation .variableDefinitions; if (!variableDefinitions) return []; const { errors } = (0, values_1.getVariableValues)(operationContext.schema, variableDefinitions, requestContext.request.variables || {}); if (errors) { (0, opentelemetry_1.recordExceptions)(span, errors, this.config.telemetry); span.setStatus({ code: api_1.SpanStatusCode.ERROR }); } return errors || []; } catch (err) { (0, opentelemetry_1.recordExceptions)(span, [err], this.config.telemetry); span.setStatus({ code: api_1.SpanStatusCode.ERROR }); throw err; } finally { span.end(); } }); } async performCleanupAndLogErrors() { if (this.toDispose.length === 0) return; await Promise.all(this.toDispose.map((p) => p().catch((e) => { var _a; this.logger.error('Error occured while calling user provided `cleanup` function: ' + ((_a = e.message) !== null && _a !== void 0 ? _a : e)); }))); this.toDispose = []; } async stop() { switch (this.state.phase) { case 'initialized': case 'failed to load': case 'stopped': return; case 'stopping': await this.state.stoppingDonePromise; if (this.state.phase !== 'stopped') { throw Error(`Expected to be stopped when done stopping, but instead ${this.state.phase}`); } return; case 'loaded': const stoppingDonePromise = this.performCleanupAndLogErrors(); this.state = { phase: 'stopping', stoppingDonePromise, }; await stoppingDonePromise; this.state = { phase: 'stopped' }; return; case 'updating schema': { throw Error("`ApolloGateway.stop` shouldn't be called from inside a schema change listener"); } default: throw new UnreachableCaseError(this.state); } } __testing() { return { state: this.state, compositionId: this.compositionId, supergraphSdl: this.supergraphSdl, queryPlanner: this.queryPlanner, }; } } exports.ApolloGateway = ApolloGateway; ApolloGateway.prototype.onSchemaChange = (0, util_1.deprecate)(ApolloGateway.prototype.onSchemaChange, `'ApolloGateway.prototype.onSchemaChange' is deprecated. Use 'ApolloGateway.prototype.onSchemaLoadOrUpdate' instead.`); function approximateObjectSize(obj) { return Buffer.byteLength(JSON.stringify(obj), 'utf8'); } class UnreachableCaseError extends Error { constructor(val) { super(`Unreachable case: ${val}`); } } __exportStar(require("./datasources"), exports); var supergraphManagers_2 = require("./supergraphManagers"); Object.defineProperty(exports, "UplinkFetcherError", { enumerable: true, get: function () { return supergraphManagers_2.UplinkFetcherError; } }); //# sourceMappingURL=index.js.map