@graphql-mesh/compose-cli
Version:
116 lines (115 loc) • 4.02 kB
JavaScript
import { buildClientSchema, buildSchema, getIntrospectionQuery, } from 'graphql';
export function loadGraphQLHTTPSubgraph(subgraphName, { endpoint, method, useGETForQueries, operationHeaders, credentials, retry, timeout, source, schemaHeaders, spec = false, }) {
return (ctx) => {
let schema$;
function handleFetchedSchema(schema) {
return addAnnotations({
kind: 'http',
subgraph: subgraphName,
location: endpoint,
headers: operationHeaders,
options: {
method,
useGETForQueries,
credentials,
retry,
timeout,
},
}, schema);
}
if (source) {
schema$ = ctx
.fetch(source, {
headers: schemaHeaders,
})
.then(res => res.text())
.then(sdl => buildSchema(sdl, {
assumeValidSDL: true,
assumeValid: true,
noLocation: true,
}))
.then(schema => addAnnotations({
kind: 'http',
subgraph: subgraphName,
location: endpoint,
headers: operationHeaders,
options: {
method,
useGETForQueries,
credentials,
retry,
timeout,
},
}, schema));
}
else {
switch (spec) {
case false:
schema$ = ctx
.fetch(endpoint, {
method: method || (useGETForQueries ? 'GET' : 'POST'),
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: getIntrospectionQuery(),
}),
})
.then(res => {
assertResponseOk(res);
return res.json();
})
.then((result) => buildClientSchema(result.data, {
assumeValid: true,
}));
break;
case 'federation':
schema$ = ctx
.fetch(endpoint, {
method: method || (useGETForQueries ? 'GET' : 'POST'),
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: federationIntrospectionQuery,
}),
})
.then(res => {
assertResponseOk(res);
return res.text();
})
.then(sdl => buildSchema(sdl, {
assumeValidSDL: true,
assumeValid: true,
noLocation: true,
}));
break;
default:
throw new Error(`Unsupported spec: ${spec}`);
}
}
schema$ = schema$.then(handleFetchedSchema);
return {
name: subgraphName,
schema$,
};
};
}
function addAnnotations(transportEntry, schema) {
const schemaExtensions = (schema.extensions ||= {});
schemaExtensions.directives ||= {};
schemaExtensions.directives.transport = transportEntry;
return schema;
}
const federationIntrospectionQuery = /* GraphQL */ `
query GetFederationInfo {
_service {
sdl
}
}
`;
function assertResponseOk(response) {
if (!response.ok) {
throw new Error(`Failed to load GraphQL HTTP subgraph: ${response.statusText}`);
}
}