-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshark.ts
More file actions
61 lines (56 loc) · 2.2 KB
/
shark.ts
File metadata and controls
61 lines (56 loc) · 2.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { getIntrospectionQuery, parse, print, buildClientSchema, printSchema, buildSchema, mergeTypeDefs } from './deps.ts'
async function remoteExecutor({ query, variables }, url: string) {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables })
})
return response.json()
}
async function printRemoteSchema(executor: Function, url: string) {
const instropection = await executor({ query: getIntrospectionQuery() }, url);
if (instropection?.data?.__schema) {
return printSchema(buildClientSchema(instropection.data))
}
}
async function getResolver(schemas: string, url: string) {
const schema = parse(schemas);
const rootValue = {};
for await (const objDef of schema.definitions) {
if (objDef.name.value === 'Query' || objDef.name.value === 'Mutation') {
for await (const funcField of objDef.fields) {
rootValue[funcField.name.value] = async (args: any, context: any) => {
const { query, variables } = await context.request.clone().json();
const headers = await context.request.headers;
const response = await fetch(url, {
method: 'POST',
headers,
body: JSON.stringify({ query, variables })
})
const json = await response.json()
return json.data[funcField.name.value]
}
}
}
}
return rootValue
}
async function mergeRemoteSchema(urls: string[]) {
const schemas: string[] = [];
const rootValue = {};
for await (const url of urls) {
const schema = await printRemoteSchema(remoteExecutor, url);
const executor = await getResolver(schema, url);
Object.assign(rootValue, executor);
schemas.push(schema);
}
const typeDefs = mergeTypeDefs(schemas);
const schemaDefs = print(typeDefs);
const schema = buildSchema(`
${schemaDefs}
`)
return { schema, rootValue }
}
export default async (endpoints: string[]) => {
return await mergeRemoteSchema(endpoints);
}