UNPKG

@graphql-hive/gateway-plugin-console-sdk

Version:
231 lines (230 loc) • 13.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createSupergraphSDLFetcher = exports.createServicesFetcher = exports.createSchemaFetcher = exports.atLeastOnceSampler = void 0; exports.createHive = createHive; exports.useHive = useHive; const tslib_1 = require("tslib"); const graphql_1 = require("graphql"); const tiny_lru_1 = require("tiny-lru"); const core_1 = require("@graphql-hive/core"); const is_entity_request_js_1 = require("./is-entity-request.js"); const version_js_1 = require("./version.js"); var core_2 = require("@graphql-hive/core"); Object.defineProperty(exports, "atLeastOnceSampler", { enumerable: true, get: function () { return core_2.atLeastOnceSampler; } }); Object.defineProperty(exports, "createSchemaFetcher", { enumerable: true, get: function () { return core_2.createSchemaFetcher; } }); Object.defineProperty(exports, "createServicesFetcher", { enumerable: true, get: function () { return core_2.createServicesFetcher; } }); Object.defineProperty(exports, "createSupergraphSDLFetcher", { enumerable: true, get: function () { return core_2.createSupergraphSDLFetcher; } }); function createHive(clientOrOptions) { return (0, core_1.createHive)(Object.assign(Object.assign({}, clientOrOptions), { agent: Object.assign({ name: 'hive-client-gateway-sdk', version: version_js_1.version }, clientOrOptions.agent) })); } function useHive(clientOrOptions) { var _a, _b; const hive = (0, core_1.isHiveClient)(clientOrOptions) ? clientOrOptions : createHive(Object.assign(Object.assign({}, clientOrOptions), { agent: Object.assign({ name: 'hive-client-gateway-sdk' }, clientOrOptions.agent) })); void hive.info(); const contextualCache = new WeakMap(); const statusMap = new WeakMap(); const fieldLevelMetricsEnabled = (0, core_1.isHiveClient)(clientOrOptions) ? false : (typeof clientOrOptions.usage === 'object' && ((_a = clientOrOptions.usage) === null || _a === void 0 ? void 0 : _a.fieldLevelMetricsEnabled)) || false; const operationCache = fieldLevelMetricsEnabled ? (0, tiny_lru_1.lru)((0, core_1.isHiveClient)(clientOrOptions) ? 10000 : ((_b = clientOrOptions.cache) !== null && _b !== void 0 ? _b : 10000)) : null; let latestSchema = null; return { onFetch({ executionRequest }) { if (!executionRequest) { return; } return function onFetchDone({ response }) { statusMap.set(executionRequest, response.status); }; }, onSubgraphExecute({ executionRequest, subgraphName, subgraph: subgraphSchema }) { var _a, _b, _c; if (!fieldLevelMetricsEnabled || !executionRequest.context) { return; } const cache = contextualCache.get(executionRequest.context); if (!cache) { return; } const finishSubRequest = cache.collector.subrequest({ subgraph: subgraphName, type: (0, is_entity_request_js_1.isEntityRequest)(executionRequest.document) ? 'ENTITY' : 'ROOT', paths: ((_a = executionRequest.info) === null || _a === void 0 ? void 0 : _a.path) ? [(0, graphql_1.responsePathAsArray)(executionRequest.info.path).join('.')] : (_c = (0, core_1.getDefinedRootType)(subgraphSchema, (_b = executionRequest.operationType) !== null && _b !== void 0 ? _b : graphql_1.OperationTypeNode.QUERY)) === null || _c === void 0 ? void 0 : _c.name, }); return function onSubgraphExecuteDone({ result }) { var _a; if (!(0, core_1.isAsyncIterable)(result)) { finishSubRequest({ status: (_a = statusMap.get(executionRequest)) !== null && _a !== void 0 ? _a : 200, subgraphSchema, result, // The Rust query planner generates and caches this document up front. // This depends on the operation and variables. // So if we need to add typenames to the request, it needs to happen // here also. E.g. `addHiveTypenames(executionRequest.document, subgraphSchema)`. // But for the js gateway execution, this is redundant and an unnecessary expense. document: executionRequest.document, }); } }; }, onSchemaChange({ schema }) { hive.reportSchema({ schema }); latestSchema = schema; operationCache === null || operationCache === void 0 ? void 0 : operationCache.clear(); }, onParams(context) { if ((context.params.query || 'documentId' in context.params) && latestSchema) { contextualCache.set(context.context, { collector: hive.collectUsage(), paramsArgs: context.params, }); } }, onExecute({ args, context, setExecuteFn, executeFn }) { var _a; const ctx = args.contextValue || context; const cache = contextualCache.get(ctx); if (!cache) return; cache.executionArgs = args; if (fieldLevelMetricsEnabled && operationCache && latestSchema) { // Validation must run against the client document. Add the metadata fields only // to the document passed to execution and cache that transformed document. const query = (_a = args.document.loc) === null || _a === void 0 ? void 0 : _a.source.body; const cachedDocument = query ? operationCache.get(query) : undefined; const modifiedDocument = cachedDocument === true ? args.document : cachedDocument || (0, core_1.addHiveTypenames)(args.document, latestSchema); if (query && cachedDocument === undefined) { operationCache.set(query, args.document === modifiedDocument || modifiedDocument); } if (args.document !== modifiedDocument) { setExecuteFn(executionArgs => executeFn(Object.assign(Object.assign({}, executionArgs), { document: modifiedDocument }))); } cache.document = modifiedDocument; } return { onExecuteDone({ result, args }) { var _a, _b, _c; if (!(0, core_1.isAsyncIterable)(result)) { if (result.errors) { const gatewayErrors = (_a = result.errors) === null || _a === void 0 ? void 0 : _a.filter(e => { var _a, _b; /** * DOWNSTREAM_SERVICE_ERROR is set by the executor to wrap subgraph errors. A serviceName is also * used to indicate the source of the error. If either of these are found, then it's safe to assume * the error was not thrown in the gateway. */ return ((_a = e.extensions) === null || _a === void 0 ? void 0 : _a.code) !== 'DOWNSTREAM_SERVICE_ERROR' && !((_b = e.extensions) === null || _b === void 0 ? void 0 : _b.serviceName); }); if (cache && (gatewayErrors === null || gatewayErrors === void 0 ? void 0 : gatewayErrors.length) > 0) { cache.collector.trackGatewayErrors({ errors: gatewayErrors }); } } args.contextValue.waitUntil(cache.collector.finish(Object.assign(Object.assign({}, args), { document: (_c = (_b = cache.document) !== null && _b !== void 0 ? _b : ctx.document) !== null && _c !== void 0 ? _c : args.document }), result, cache.experimental__documentId)); return; } const errors = []; return { onNext({ result: iterResult }) { if (iterResult.errors) { errors.push(...iterResult.errors); } }, onEnd() { var _a; ctx.waitUntil(cache.collector.finish(Object.assign(Object.assign({}, args), { document: (_a = cache.document) !== null && _a !== void 0 ? _a : args.document }), // how to pass in data here? errors.length ? { errors } : {}, cache.experimental__documentId)); }, }; }, }; }, onSubscribe({ args, context }) { const ctx = args.contextValue || context; const record = contextualCache.get(ctx); return { onSubscribeResult() { var _a, _b, _c; const experimental__persistedDocumentHash = record === null || record === void 0 ? void 0 : record.experimental__documentId; hive.collectSubscriptionUsage({ args: Object.assign(Object.assign({}, args), { document: (_c = (_a = record === null || record === void 0 ? void 0 : record.document) !== null && _a !== void 0 ? _a : (_b = record === null || record === void 0 ? void 0 : record.executionArgs) === null || _b === void 0 ? void 0 : _b.document) !== null && _c !== void 0 ? _c : args.document }), experimental__persistedDocumentHash, }); }, }; }, async onResultProcess({ serverContext, result, setResult }) { const record = contextualCache.get(serverContext); if (!record || Array.isArray(result) || (0, core_1.isAsyncIterable)(result) || record.executionArgs) { if (fieldLevelMetricsEnabled) { if ((0, core_1.isAsyncIterable)(result)) { const modifyStream = function () { return tslib_1.__asyncGenerator(this, arguments, function* () { var _a, e_1, _b, _c; try { for (var _d = true, result_1 = tslib_1.__asyncValues(result), result_1_1; result_1_1 = yield tslib_1.__await(result_1.next()), _a = result_1_1.done, !_a; _d = true) { _c = result_1_1.value; _d = false; const r = _c; (0, core_1.hideInjectedTypenames)(r.data); yield yield tslib_1.__await(r); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (!_d && !_a && (_b = result_1.return)) yield tslib_1.__await(_b.call(result_1)); } finally { if (e_1) throw e_1.error; } } }); }; setResult(modifyStream()); } else if (Array.isArray(result)) { for (let r of result) { (0, core_1.hideInjectedTypenames)(r.data); } } else { (0, core_1.hideInjectedTypenames)(result.data); } } return; } if (record.paramsArgs.query && latestSchema) { try { let doc = record.document; if (!doc) { doc = (0, graphql_1.parse)(record.paramsArgs.query); } serverContext.waitUntil(record.collector.finish({ document: doc, schema: latestSchema, variableValues: record.paramsArgs.variables, operationName: record.paramsArgs.operationName, contextValue: serverContext, }, result, record.experimental__documentId)); } catch (err) { // Fail silently if parse fails inside cached block handling } } if (fieldLevelMetricsEnabled) { (0, core_1.hideInjectedTypenames)(result.data); } }, onDispose() { return hive.dispose(); }, }; }