Skip to content

Commit

Permalink
update deps & support 'graphiql' endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
o-az committed Nov 19, 2023
1 parent 98d165c commit d295796
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 47 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml → .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: Deploy

on:
workflow_dispatch:
Expand All @@ -21,11 +21,11 @@ env:
jobs:
deploy:
name: "Deploy"
timeout-minutes: 3.69
timeout-minutes: 2
runs-on: ["ubuntu-latest"]
steps:
- name: "Checkout"
uses: actions/checkout@v3
uses: actions/checkout@v4.1.1

- name: "Setup Bun"
uses: oven-sh/setup-bun@v1
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@ or get the `SDL`

[`https://introspect.lagon.dev/sdl/https://spacex-production.up.railway.app`](https://introspect.lagon.dev/sdl/https://spacex-production.up.railway.app)

or play around with it in a live playground [https://introspect.lagon.dev/playground/https://spacex-production.up.railway.app](https://introspect.lagon.dev/playground/https://spacex-production.up.railway.app)
or play around with it in a live playground

[`https://introspect.lagon.dev/playground/https://spacex-production.up.railway.app`](https://introspect.lagon.dev/playground/https://spacex-production.up.railway.app)

By default API will return schema as `JSON`

Expand Down
Binary file modified bun.lockb
Binary file not shown.
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
"deploy": "lagon deploy --production"
},
"dependencies": {
"graphql": "^16.7.1"
"graphql": "^16.8.1"
},
"devDependencies": {
"bun-types": "^0.7.1",
"typescript": "^5.1.6"
"bun-types": "^1.0.13",
"typescript": "^5.2.2"
},
"license": "GPL-3.0-or-later",
"keywords": [
Expand Down
33 changes: 10 additions & 23 deletions src/graphql/graphiql.html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,48 +19,35 @@ export function htmlPage({ endpoint }: { endpoint: string }) {
width: 100%;
overflow: hidden;
}
#graphiql {
height: 100vh;
}
</style>
<script
crossorigin
src="https://unpkg.com/react/umd/react.development.js"
></script>
<script
crossorigin
src="https://unpkg.com/react-dom/umd/react-dom.development.js"
></script>
<script
src="https://unpkg.com/graphiql/graphiql.min.js"
type="application/javascript"
></script>
<script crossorigin src="https://unpkg.com/react/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/graphiql/graphiql.min.js" type="application/javascript"></script>
<link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" />
<script
src="https://unpkg.com/@graphiql/plugin-explorer/dist/index.umd.js"
crossorigin
></script>
<link
rel="stylesheet"
href="https://unpkg.com/@graphiql/plugin-explorer/dist/style.css"
/>
<link rel="stylesheet" href="https://unpkg.com/@graphiql/plugin-explorer/dist/style.css" />
</head>
<body>
<div id="graphiql">Loading...</div>
<script>
const root = ReactDOM.createRoot(document.getElementById('graphiql'));
const root = ReactDOM.createRoot(document.getElementById('graphiql'))
const fetcher = GraphiQL.createFetcher({
url: "${endpoint}",
});
const explorerPlugin = GraphiQLPluginExplorer.explorerPlugin();
url: '${endpoint}',
})
const explorerPlugin = GraphiQLPluginExplorer.explorerPlugin()
root.render(
React.createElement(GraphiQL, {
fetcher,
defaultEditorToolsVisibility: true,
plugins: [explorerPlugin],
}),
);
})
)
</script>
</body>
</html>
Expand Down
24 changes: 17 additions & 7 deletions src/graphql/schema.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,37 @@
import type { Json } from '#/types'
import { buildClientSchema, printSchema, getIntrospectionQuery } from 'graphql'
import type { IntrospectionOptions } from 'graphql'
import {
printSchema,
buildClientSchema,
getIntrospectionQuery,
type IntrospectionOptions,
} from 'graphql'
import type { Json } from '#/types.ts'

export function jsonSchemaToSDL(jsonString: string) {
const json = JSON.parse(jsonString)
const schema = buildClientSchema(json.data)
return printSchema(schema)
}

export async function fetchJsonSchema({ url, minimal = true }: { url: string; minimal?: boolean }): Promise<Json> {
export async function fetchJsonSchema({
url,
minimal = true,
}: {
url: string
minimal?: boolean
}): Promise<Json> {
const introspectionOptions = {
descriptions: !minimal,
directiveIsRepeatable: !minimal,
schemaDescription: !minimal
schemaDescription: !minimal,
} satisfies IntrospectionOptions
try {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body: JSON.stringify({
query: getIntrospectionQuery(introspectionOptions),
variable: {}
})
variable: {},
}),
})

if (!response.ok) throw new Error(`Failed to fetch from ${url}: ${response.statusText}`)
Expand Down
20 changes: 12 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { fetchJsonSchema, jsonSchemaToSDL } from '#/graphql/schema'
import { isURL, formatMessages, LANDING_MESSAGE } from '#/utilities'
import { fetchJsonSchema, jsonSchemaToSDL } from '#/graphql/schema.ts'
import { isURL, formatMessages, LANDING_MESSAGE } from '#/utilities.ts'

/**
* Route Options
Expand Down Expand Up @@ -27,11 +27,11 @@ export async function handler(request: Request): Promise<Response> {
)
}

if (requestedFormat === 'playground') {
const { htmlPage } = await import('#/graphql/graphiql.html')
if (['playground', 'graphiql'].includes(requestedFormat)) {
const { htmlPage } = await import('#/graphql/graphiql.html.ts')
return new Response(htmlPage({ endpoint: introspectionURL }), {
status: 200,
headers: { 'Content-Type': 'text/html' }
headers: { 'Content-Type': 'text/html' },
})
}

Expand All @@ -42,20 +42,24 @@ export async function handler(request: Request): Promise<Response> {

return new Response(sdlSchema, {
status: sdlSchema.startsWith('Encountered an error') ? 400 : 200,
headers: { 'Content-Type': 'text/plain' }
headers: { 'Content-Type': 'text/plain' },
})
}

return new Response(JSON.stringify(jsonSchema), {
status: 200,
headers: { 'Content-Type': 'application/json' }
headers: { 'Content-Type': 'application/json' },
})
} catch (error) {
const message = error instanceof Error ? error.message : `Encountered an error: ${error}`
console.error(message)

return new Response(
formatMessages(message, 'The introspection URL should be the URL of a GraphQL endpoint.', LANDING_MESSAGE),
formatMessages(
message,
'The introspection URL should be the URL of a GraphQL endpoint.',
LANDING_MESSAGE
),
{ status: 500, headers: { 'Content-Type': 'text/plain' } }
)
}
Expand Down
5 changes: 3 additions & 2 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
"compilerOptions": {
"module": "ESNext",
"target": "ESNext",
"noEmit": true,
"sourceMap": false,
"skipLibCheck": true,
"resolveJsonModule": true,
"verbatimModuleSyntax": true,
"moduleResolution": "bundler",
"moduleResolution": "Bundler",
"noUncheckedIndexedAccess": true,
"allowImportingTsExtensions": true,
"allowSyntheticDefaultImports": true,
"lib": ["ESNext", "DOM", "DOM.Iterable"],
"noPropertyAccessFromIndexSignature": true,
"types": ["node", "bun-types"],
"types": ["bun-types"],
"paths": {
"#/*": ["./src/*"]
}
Expand Down

0 comments on commit d295796

Please sign in to comment.