UNPKG

@graphql-hive/yoga

Version:
189 lines (188 loc) • 9.11 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 = tslib_1.__importDefault(require("tiny-lru")); const core_1 = require("@graphql-hive/core"); const plugin_persisted_operations_1 = require("@graphql-yoga/plugin-persisted-operations"); 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-yoga' }, clientOrOptions.agent) })); } function useHive(clientOrOptions) { const hive = (0, core_1.isHiveClient)(clientOrOptions) ? clientOrOptions : createHive(clientOrOptions); void hive.info(); if (hive[core_1.autoDisposeSymbol]) { if (global.process) { const signals = Array.isArray(hive[core_1.autoDisposeSymbol]) ? hive[core_1.autoDisposeSymbol] : ['SIGINT', 'SIGTERM']; for (const signal of signals) { process.once(signal, () => hive.dispose()); } } else { console.error('It seems that GraphQL Hive is not being executed in Node.js. ' + 'Please attempt manual client disposal and use autoDispose: false option.'); } } const parsedDocumentCache = (0, tiny_lru_1.default)(10000); let latestSchema = null; const contextualCache = new WeakMap(); return { onSchemaChange({ schema }) { hive.reportSchema({ schema }); latestSchema = schema; }, onParams(context) { // we set the params if there is either a query or documentId in the request if ((context.params.query || 'documentId' in context.params) && latestSchema) { contextualCache.set(context.context, { callback: hive.collectUsage(), paramsArgs: context.params, }); } }, // since response-cache modifies the executed GraphQL document, we need to extract it after parsing. onParse(parseCtx) { return ctx => { if (ctx.result.kind === graphql_1.Kind.DOCUMENT) { const record = contextualCache.get(ctx.context); if (record) { record.parsedDocument = ctx.result; parsedDocumentCache.set(parseCtx.params.source, ctx.result); } } }; }, onExecute() { return { onExecuteDone({ args, result }) { var _a; const record = contextualCache.get(args.contextValue); if (!record) { return; } record.executionArgs = args; if (!(0, core_1.isAsyncIterable)(result)) { void record.callback(Object.assign(Object.assign({}, record.executionArgs), { document: (_a = record.parsedDocument) !== null && _a !== void 0 ? _a : record.executionArgs.document }), result, record.experimental__documentId); return; } const errors = []; return { onNext(ctx) { if (!ctx.result.errors) { return; } errors.push(...ctx.result.errors); }, onEnd() { void record.callback(args, errors.length ? { errors } : {}, record.experimental__documentId); }, }; }, }; }, onSubscribe(context) { const record = contextualCache.get(context.args.contextValue); return { onSubscribeResult() { const experimental__persistedDocumentHash = record === null || record === void 0 ? void 0 : record.experimental__documentId; hive.collectSubscriptionUsage({ args: context.args, experimental__persistedDocumentHash, }); }, }; }, onResultProcess(context) { const record = contextualCache.get(context.serverContext); if (!record || Array.isArray(context.result) || (0, core_1.isAsyncIterable)(context.result) || record.executionArgs) { return; } // Report if execution was skipped due to response cache ( Symbol.for('servedFromResponseCache') in context.result) if (record.paramsArgs.query && latestSchema && Symbol.for('servedFromResponseCache') in context.result) { try { let document = parsedDocumentCache.get(record.paramsArgs.query); if (document === undefined) { document = (0, graphql_1.parse)(record.paramsArgs.query); parsedDocumentCache.set(record.paramsArgs.query, document); } void record.callback({ document, schema: latestSchema, variableValues: record.paramsArgs.variables, operationName: record.paramsArgs.operationName, }, context.result, record.experimental__documentId); } catch (err) { console.error(err); } } }, onPluginInit({ addPlugin }) { const { experimental__persistedDocuments } = hive; if (!experimental__persistedDocuments) { return; } addPlugin((0, plugin_persisted_operations_1.usePersistedOperations)({ extractPersistedOperationId(body, request) { if ('documentId' in body && typeof body.documentId === 'string') { return body.documentId; } const documentId = new URL(request.url).searchParams.get('documentId'); if (documentId) { return documentId; } return null; }, async getPersistedOperation(key, request, context) { const document = await experimental__persistedDocuments.resolve(key); // after we resolve the document we need to update the cache record to contain the resolved document if (document) { const record = contextualCache.get(context); if (record) { record.experimental__documentId = key; record.paramsArgs = Object.assign(Object.assign({}, record.paramsArgs), { query: document }); } } return document; }, allowArbitraryOperations(request) { return experimental__persistedDocuments.allowArbitraryDocuments({ headers: request.headers, }); }, customErrors: { keyNotFound() { return new graphql_1.GraphQLError('Persisted document not found.', { extensions: { code: 'PERSISTED_DOCUMENT_NOT_FOUND' }, }); }, notFound() { return new graphql_1.GraphQLError('Persisted document not found.', { extensions: { code: 'PERSISTED_DOCUMENT_NOT_FOUND' }, }); }, persistedQueryOnly() { return new graphql_1.GraphQLError('No persisted document provided.', { extensions: { code: 'PERSISTED_DOCUMENT_REQUIRED' }, }); }, }, })); }, }; }