Skip to content

Commit

Permalink
Add shark js
Browse files Browse the repository at this point in the history
  • Loading branch information
anak10thn committed Oct 12, 2022
1 parent bd0d15d commit eb35d81
Show file tree
Hide file tree
Showing 13 changed files with 257 additions and 1 deletion.
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
deno
deno.exe
ngrok
ngrok.exe
log.txt
uploads
my_uploads
temp_uploads
*.sqlite
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# shark
# Shark
3 changes: 3 additions & 0 deletions deps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { Server } from "https://deno.land/x/kilat/mod.ts";
export { GraphQLHTTP, getIntrospectionQuery, parse, print, buildClientSchema, printSchema, buildSchema } from 'https://deno.land/x/kilatgraphql/mod.ts'
export { mergeTypeDefs } from 'https://cdn.skypack.dev/@graphql-tools/merge/index.js'
4 changes: 4 additions & 0 deletions example/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
PWDIR=$(PWD)

all:
@(trap 'kill 0' SIGINT;cd $(PWDIR)/graphql && luwak server.ts & cd $(PWDIR)/graphql2 && luwak server.ts & luwak server.ts)
42 changes: 42 additions & 0 deletions example/graphql/lambdas/Example/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
var coursesData = [
{
id: 1,
title: 'The Complete Node.js Developer Course',
author: 'Andrew Mead, Rob Percival',
description: 'Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!',
topic: 'Node.js',
url: 'https://codingthesmartway.com/courses/nodejs/'
},
{
id: 2,
title: 'Node.js, Express & MongoDB Dev to Deployment',
author: 'Brad Traversy',
description: 'Learn by example building & deploying real-world Node.js applications from absolute scratch',
topic: 'Node.js',
url: 'https://codingthesmartway.com/courses/nodejs-express-mongodb/'
},
{
id: 3,
title: 'JavaScript: Understanding The Weird Parts',
author: 'Anthony Alicea',
description: 'An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.',
topic: 'JavaScript',
url: 'https://codingthesmartway.com/courses/understand-javascript/'
}
]

export async function getExample(args) {
var id = args.id;
return coursesData.filter(course => {
return course.id == id;
})[0];
}

export function getExamples(args) {
if (args.topic) {
var topic = args.topic;
return coursesData.filter(course => course.topic === topic);
} else {
return coursesData;
}
}
13 changes: 13 additions & 0 deletions example/graphql/lambdas/Example/schema.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type Query {
getExample(id: Int!): Example
getExamples(topic: String): [Example]
},

type Example {
id: Int
title: String
author: String
description: String
topic: String
url: String
}
4 changes: 4 additions & 0 deletions example/graphql/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Remora } from 'https://deno.land/x/remora/mod.ts'

const server = new Remora("./lambdas");
await server.listen(3001);
42 changes: 42 additions & 0 deletions example/graphql2/lambdas/Example2/query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
var coursesData = [
{
id: 1,
title: 'The Complete Node.js Developer Course',
author: 'Andrew Mead, Rob Percival',
description: 'Learn Node.js by building real-world applications with Node, Express, MongoDB, Mocha, and more!',
topic: 'Node.js',
url: 'https://codingthesmartway.com/courses/nodejs/'
},
{
id: 2,
title: 'Node.js, Express & MongoDB Dev to Deployment',
author: 'Brad Traversy',
description: 'Learn by example building & deploying real-world Node.js applications from absolute scratch',
topic: 'Node.js',
url: 'https://codingthesmartway.com/courses/nodejs-express-mongodb/'
},
{
id: 3,
title: 'JavaScript: Understanding The Weird Parts',
author: 'Anthony Alicea',
description: 'An advanced JavaScript course for everyone! Scope, closures, prototypes, this, build your own framework, and more.',
topic: 'JavaScript',
url: 'https://codingthesmartway.com/courses/understand-javascript/'
}
]

export function getExample2(args) {
var id = args.id;
return coursesData.filter(course => {
return course.id == id;
})[0];
}

export function getExamples2(args) {
if (args.topic) {
var topic = args.topic;
return coursesData.filter(course => course.topic === topic);
} else {
return coursesData;
}
}
13 changes: 13 additions & 0 deletions example/graphql2/lambdas/Example2/schema.gql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type Query {
getExample2(id: Int!): Example2
getExamples2(topic: String): [Example2]
},

type Example2 {
id: Int
title: String
author: String
description: String
topic: String
url: String
}
26 changes: 26 additions & 0 deletions example/graphql2/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Remora } from 'https://deno.land/x/remora/mod.ts'

/*
TEST QUERY
{
getExamples(topic:"JavaScript") {
id
title
author
description
topic
url
}
getExample(id:2){
id
title
author
description
}
}
*/

const server = new Remora("./lambdas");
await server.listen(3002);
14 changes: 14 additions & 0 deletions example/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
query{
getExample2(id:1){
id
title
author
description
}
}
*/

import { Shark } from '../mod.ts'
const server = new Shark(["http://localhost:3001/graphql", "http://localhost:3002/graphql"]);
await server.listen();
25 changes: 25 additions & 0 deletions mod.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Server, GraphQLHTTP } from './deps.ts'
import shark from './shark.ts'
export class Shark {
endpoints: string[];
server: Server;
constructor(endpoints: string[]) {
this.endpoints = endpoints;
this.server = new Server();
}

async listen(port: number = parseInt(Deno.env.get("PORT")) || 8000) {
const { schema, rootValue } = await shark(this.endpoints);
this.server.post(
"/graphql",
async (ctx: any, next: any) => {
const resp = await GraphQLHTTP({ schema, rootValue, context: (request) => ({ request }), graphiql: true })(ctx.req);
ctx.res = resp;
await next();
},
);
console.log(`Shark server listen to http://localhost:${port}`);
await this.server.listen({ port });
}

}
61 changes: 61 additions & 0 deletions shark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,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);
}

0 comments on commit eb35d81

Please sign in to comment.