@graphql-hive/apollo
Version:
GraphQL Hive + Apollo Server
279 lines (278 loc) • 12.9 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createSupergraphSDLFetcher = exports.createServicesFetcher = exports.createSchemaFetcher = exports.atLeastOnceSampler = void 0;
exports.createSupergraphManager = createSupergraphManager;
exports.createHive = createHive;
exports.useHive = useHive;
const tslib_1 = require("tslib");
const graphql_1 = require("graphql");
const core_1 = require("@graphql-hive/core");
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 createSupergraphManager(_a) {
var { pollIntervalInMs } = _a, superGraphFetcherOptions = tslib_1.__rest(_a, ["pollIntervalInMs"]);
pollIntervalInMs = pollIntervalInMs !== null && pollIntervalInMs !== void 0 ? pollIntervalInMs : 30000;
const fetchSupergraph = (0, core_1.createSupergraphSDLFetcher)(superGraphFetcherOptions);
let timer = null;
return {
async initialize(hooks) {
const initialResult = await fetchSupergraph();
function poll() {
timer = setTimeout(async () => {
var _a;
try {
const result = await fetchSupergraph();
if (result.supergraphSdl) {
(_a = hooks.update) === null || _a === void 0 ? void 0 : _a.call(hooks, result.supergraphSdl);
}
}
catch (error) {
console.error(`Failed to update supergraph: ${error instanceof Error ? error.message : error}`);
}
poll();
}, pollIntervalInMs);
}
poll();
return {
supergraphSdl: initialResult.supergraphSdl,
cleanup: async () => {
if (timer) {
clearTimeout(timer);
}
},
};
},
};
}
function addRequestWithHeaders(context, http) {
if (!!http && !('request' in context)) {
context.request = {
headers: http.headers,
};
}
return context;
}
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();
return {
requestDidStart(context) {
var _a;
// `overallCachePolicy` does not exist in v0
const isLegacyV0 = !('overallCachePolicy' in context);
// `context` does not exist in v4, it is `contextValue` instead
const isLegacyV3 = 'context' in context;
let doc;
let didResolveSource = false;
const complete = hive.collectUsage();
const args = {
schema: context.schema,
get document() {
return doc;
},
operationName: context.operationName,
contextValue: addRequestWithHeaders(isLegacyV3 ? context.context : context.contextValue, (_a = context.request) === null || _a === void 0 ? void 0 : _a.http),
variableValues: context.request.variables,
};
if (isLegacyV0) {
return {
didResolveSource() {
didResolveSource = true;
},
willSendResponse(ctx) {
if (!didResolveSource) {
void complete(args, {
action: 'abort',
reason: 'Did not resolve source',
logging: false,
});
return;
}
doc = ctx.document;
void complete(args, ctx.response);
},
};
}
let didFailValidation = false;
if (isLegacyV3) {
return Promise.resolve({
didResolveSource() {
didResolveSource = true;
},
async validationDidStart() {
return function onErrors(errors) {
if (errors === null || errors === void 0 ? void 0 : errors.length) {
didFailValidation = true;
}
};
},
async willSendResponse(ctx) {
if (didFailValidation) {
void complete(args, {
action: 'abort',
reason: 'Validation failed',
logging: false,
});
return;
}
if (!didResolveSource) {
void complete(args, {
action: 'abort',
reason: 'Did not resolve source',
logging: false,
});
return;
}
if (!ctx.document) {
const details = ctx.operationName ? `operationName: ${ctx.operationName}` : '';
void complete(args, {
action: 'abort',
reason: 'Document is not available' + (details ? ` (${details})` : ''),
logging: true,
});
return;
}
doc = ctx.document;
void complete(args, ctx.response);
},
});
}
return (async () => {
var _a;
let persistedDocumentError = null;
let persistedDocumentHash;
if (hive.experimental__persistedDocuments) {
if (((_a = context.request.http) === null || _a === void 0 ? void 0 : _a.body) &&
typeof context.request.http.body === 'object' &&
'documentId' in context.request.http.body &&
typeof context.request.http.body.documentId === 'string') {
persistedDocumentHash = context.request.http.body.documentId;
const document = await hive.experimental__persistedDocuments.resolve(context.request.http.body.documentId);
if (document) {
context.request.query = document;
}
else {
context.request.query = '{__typename}';
persistedDocumentError = new graphql_1.GraphQLError('Persisted document not found.', {
extensions: {
code: 'PERSISTED_DOCUMENT_NOT_FOUND',
http: {
status: 400,
},
},
});
}
}
else if (false ===
(await hive.experimental__persistedDocuments.allowArbitraryDocuments({
headers: {
get(name) {
var _a, _b, _c;
return (_c = (_b = (_a = context.request.http) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b.get(name)) !== null && _c !== void 0 ? _c : null;
},
},
}))) {
context.request.query = '{__typename}';
persistedDocumentError = new graphql_1.GraphQLError('No persisted document provided.', {
extensions: {
code: 'PERSISTED_DOCUMENT_REQUIRED',
http: {
status: 400,
},
},
});
}
}
// v4
return {
didResolveSource() {
didResolveSource = true;
},
async validationDidStart() {
return function onErrors(errors) {
if (errors === null || errors === void 0 ? void 0 : errors.length) {
didFailValidation = true;
}
};
},
didResolveOperation() {
if (persistedDocumentError) {
throw persistedDocumentError;
}
},
async willSendResponse(ctx) {
if (didFailValidation) {
void complete(args, {
action: 'abort',
reason: 'Validation failed',
logging: false,
}, persistedDocumentHash);
return;
}
if (!didResolveSource) {
void complete(args, {
action: 'abort',
reason: 'Did not resolve source',
logging: false,
}, persistedDocumentHash);
return;
}
if (!ctx.document) {
const details = ctx.operationName ? `operationName: ${ctx.operationName}` : '';
void complete(args, {
action: 'abort',
reason: 'Document is not available' + (details ? ` (${details})` : ''),
logging: true,
}, persistedDocumentHash);
return;
}
doc = ctx.document;
if (ctx.response.body.kind === 'incremental') {
void complete(args, {
action: 'abort',
reason: '@defer and @stream is not supported by Hive',
logging: true,
}, persistedDocumentHash);
}
else {
void complete(args, ctx.response.body.singleResult, persistedDocumentHash);
}
},
};
})();
},
serverWillStart(ctx) {
// `engine` does not exist in v3
const isLegacyV0 = 'engine' in ctx;
hive.reportSchema({ schema: ctx.schema });
if (isLegacyV0) {
return {
async serverWillStop() {
if (hive[core_1.autoDisposeSymbol]) {
await hive.dispose();
}
},
};
}
// Works on v3 and v4
return Promise.resolve({
async serverWillStop() {
if (hive[core_1.autoDisposeSymbol]) {
await hive.dispose();
}
},
schemaDidLoadOrUpdate(schemaContext) {
if (ctx.schema !== schemaContext.apiSchema) {
hive.reportSchema({ schema: schemaContext.apiSchema });
}
},
});
},
};
}
;