Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V2 #21

Merged
merged 15 commits into from
Nov 9, 2023
Merged

V2 #21

2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
with:
deno-version: v1.x
- name: Run tests
run: deno test -A --location "http://127.0.0.1" --coverage=coverage
run: deno task test
- name: Create coverage report
run: deno coverage ./coverage --lcov > coverage.lcov
- name: Coveralls
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
"deno.lint": true,
"deno.unstable": false,
"editor.formatOnSave": true,
"[typescript]": { "editor.defaultFormatter": "denoland.vscode-deno" }
"[typescript]": { "editor.defaultFormatter": "denoland.vscode-deno" },
"eslint.enable": false
}
14 changes: 5 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,12 @@

# gql

> I'm building [Stauro](https://flash-dev.vercel.app) - a service to deploy web apps on the new decentralized stack.
>
> If you'd like to try or collab, [dm](https://t.me/v_1rtl) or [email](mailto:[email protected])

Universal [GraphQL](https://www.graphql.com/) HTTP middleware for Deno.
Universal and spec-compliant [GraphQL](https://www.graphql.com/) HTTP middleware
for Deno. Based on [graphql-http](https://github.com/graphql/graphql-http).

## Features

- ✨ Works with `Deno.serve`, [Opine](https://github.com/asos-craigmorten/opine)
and [oak](https://github.com/oakserver/oak)
- ✨ Works with `Deno.serve` and [oak](https://github.com/oakserver/oak)
- ⚡
[GraphQL Playground](https://github.com/graphql/graphql-playground/tree/master/packages/graphql-playground-html)
integration (via `graphiql: true`)
Expand Down Expand Up @@ -67,15 +63,15 @@ Deno.serve({
Then run:

```sh
$ curl -X POST localhost:3000/graphql -d '{ "query": "{ hello }" }'
$ curl -X POST localhost:3000/graphql -d '{ "query": "{ hello }" }' -H "Content-Type: application/json"
{
"data": {
"hello": "Hello World!"
}
}
```

Or in [GraphQL Playground](https://localhost:3000/graphql):
Or in the GraphQL Playground:

![image](https://user-images.githubusercontent.com/35937217/112218821-4133c800-8c35-11eb-984a-5c21fa71c229.png)

Expand Down
20 changes: 20 additions & 0 deletions audit_test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { serverAudits } from 'npm:[email protected]'

for (
const audit of serverAudits({
url: 'http://localhost:3000/graphql',
})
) {
Deno.test(audit.name, { sanitizeResources: false }, async () => {
const result = await audit.fn()
if (result.status === 'error') {
throw result.reason
}
if (result.status === 'warn') {
console.warn(result.reason)
}
if ('body' in result && result.body instanceof ReadableStream) {
await result.body.cancel()
}
})
}
35 changes: 0 additions & 35 deletions common.ts

This file was deleted.

7 changes: 7 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,12 @@
"singleQuote": true,
"semiColons": false
}
},
"tasks": {
"test": "deno test --allow-net --coverage=coverage",
"test:audit": "deno test --allow-net audit_test.ts"
},
"test": {
"exclude": ["audit_test.ts"]
}
}
563 changes: 56 additions & 507 deletions deno.lock

Large diffs are not rendered by default.

14 changes: 13 additions & 1 deletion deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,16 @@ export {
graphql,
type GraphQLArgs,
type GraphQLSchema,
} from 'npm:[email protected]'
} from 'npm:[email protected]'
export {
createHandler,
type HandlerOptions,
type OperationContext,
parseRequestParams as rawParseRequestParams,
type Request as RawRequest,
type RequestParams,
} from 'npm:[email protected]'
export {
Status,
STATUS_TEXT,
} from 'https://deno.land/[email protected]/http/status.ts'
28 changes: 10 additions & 18 deletions examples/oak.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {
Application,
Middleware,
Request as OakRequest,
Router,
} from 'https://deno.land/x/[email protected].0/mod.ts'
} from 'https://deno.land/x/[email protected].1/mod.ts'
import { GraphQLHTTP } from '../mod.ts'
import { makeExecutableSchema } from 'npm:@graphql-tools/[email protected]'
import { gql } from 'https://deno.land/x/[email protected]/mod.ts'
Expand All @@ -15,19 +16,13 @@ const typeDefs = gql`

const resolvers = {
Query: {
hello: (_root: undefined, _args: unknown, ctx: { request: Request }) => {
return `Hello World! from ${ctx.request.url}`
hello: (_root: undefined, _args: unknown, ctx: { request: OakRequest }) => {
return `Hello from ${ctx.request.url}`
},
},
}

const schema = makeExecutableSchema({ resolvers, typeDefs })

const resolve = GraphQLHTTP({
schema,
graphiql: true,
context: (request) => ({ request }),
})
const schema = makeExecutableSchema({ typeDefs, resolvers })

const handleGraphQL: Middleware = async (ctx) => {
// cast Oak request into a normal Request
Expand All @@ -37,24 +32,21 @@ const handleGraphQL: Middleware = async (ctx) => {
method: ctx.request.method,
})

const res = await resolve(req)
const res = await GraphQLHTTP<OakRequest>({
schema,
graphiql: true,
context: () => ({ request: ctx.request }),
})(req)

for (const [k, v] of res.headers.entries()) ctx.response.headers.append(k, v)

ctx.response.status = res.status
ctx.response.body = res.body
}

// Allow CORS:
// const cors: Middleware = (ctx) => {
// ctx.response.headers.append('access-control-allow-origin', '*')
// ctx.response.headers.append('access-control-allow-headers', 'Origin, Host, Content-Type, Accept')
// }

const graphqlRouter = new Router().all('/graphql', handleGraphQL)

const app = new Application().use(
// cors,
graphqlRouter.routes(),
graphqlRouter.allowedMethods(),
)
Expand Down
56 changes: 0 additions & 56 deletions examples/opine.ts

This file was deleted.

46 changes: 46 additions & 0 deletions examples/req-ctx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { GraphQLHTTP } from '../mod.ts'
import { makeExecutableSchema } from 'npm:@graphql-tools/[email protected]'
import { gql } from 'https://deno.land/x/[email protected]/mod.ts'
import type { Request as GQLRequest } from 'npm:[email protected]'

const typeDefs = gql`
type Query {
hello: String
}
`

type ReqContext = {
request: Request
isRequestContext: boolean
}

type Context = {
request: Request
originalReq: GQLRequest<Request, ReqContext>
}

const resolvers = {
Query: {
hello: (_root: unknown, _args: unknown, ctx: Context) => {
return `Hello from request context: ${ctx.originalReq.context.isRequestContext}`
},
},
}

const schema = makeExecutableSchema({ resolvers, typeDefs })

Deno.serve({
port: 3000,
onListen({ hostname, port }) {
console.log(`☁ Started on http://${hostname}:${port}`)
},
}, async (req) => {
const { pathname } = new URL(req.url)
return pathname === '/graphql'
? await GraphQLHTTP<Request, Context, ReqContext>({
schema,
graphiql: true,
context: (request) => ({ request: req, originalReq: request }),
}, () => ({ request: req, isRequestContext: true }))(req)
: new Response('Not Found', { status: 404 })
})
26 changes: 26 additions & 0 deletions graphiql/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# gql/graphiql

[![][docs-badge]][docs]

Tweaked version of
[graphql-playground-html](https://github.com/graphql/graphql-playground/tree/main/packages/graphql-playground-html)
without Electron and React environments.

## Get Started

```ts
import { renderPlaygroundPage } from 'https://deno.land/x/[email protected]/graphiql/render.ts'

const playground = renderPlaygroundPage({
endpoint: '/graphql',
})

return new Response(playground, {
headers: new Headers({
'Content-Type': 'text/html',
}),
})
```

[docs-badge]: https://img.shields.io/github/v/release/deno-libs/gql?label=Docs&logo=deno&style=for-the-badge&color=DD3FAA
[docs]: https://doc.deno.land/https/deno.land/x/gql/graphiql/render.ts
17 changes: 3 additions & 14 deletions graphiql/render.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import * as xss from 'https://esm.sh/xss'
import { filterXSS } from 'https://esm.sh/xss@1.0.14'
import { getLoadingMarkup } from './markup.ts'

const { filterXSS } = xss.default as any

export interface MiddlewareOptions {
endpoint?: string
subscriptionEndpoint?: string
workspaceName?: string
env?: any
config?: any
config?: unknown
settings?: ISettings
schema?: IntrospectionResult
tabs?: Tab[]
Expand Down Expand Up @@ -65,7 +62,6 @@ export interface IntrospectionResult {
export interface RenderPageOptions extends MiddlewareOptions {
version?: string
cdnUrl?: string
env?: any
title?: string
faviconUrl?: string | null
}
Expand All @@ -85,8 +81,6 @@ const CONFIG_ID = 'playground-config'

const filter = (val: string) => {
return filterXSS(val, {
// @ts-ignore
whiteList: [],
stripIgnoreTag: true,
stripIgnoreTagBody: ['script'],
})
Expand Down Expand Up @@ -153,7 +147,6 @@ export function renderPlaygroundPage(options: RenderPageOptions) {
extendedOptions.configString = JSON.stringify(options.config, null, 2)
}
if (!extendedOptions.endpoint && !extendedOptions.configString) {
/* tslint:disable-next-line */
console.warn(
`WARNING: You didn't provide an endpoint and don't have a .graphqlconfig. Make sure you have at least one of them.`,
)
Expand All @@ -169,11 +162,7 @@ export function renderPlaygroundPage(options: RenderPageOptions) {
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,600,700|Source+Code+Pro:400,700" rel="stylesheet">
<title>${extendedOptions.title || 'GraphQL Playground'}</title>
${
extendedOptions.env === 'react' || extendedOptions.env === 'electron'
? ''
: getCdnMarkup(extendedOptions)
}
${getCdnMarkup(extendedOptions)}
</head>
<body>
<style type="text/css">
Expand Down
Loading
Loading