Skip to content

Commit

Permalink
add support for passing headers
Browse files Browse the repository at this point in the history
  • Loading branch information
o-az committed Nov 19, 2023
1 parent b859444 commit 7faa7a5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 12 deletions.
9 changes: 8 additions & 1 deletion src/graphql/graphiql.html.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
// https://github.com/graphql/graphiql/blob/main/examples/graphiql-cdn/index.html
export function htmlPage({ endpoint }: { endpoint: string }) {
export function htmlPage({
endpoint,
headers
}: {
endpoint: string
headers?: HeadersInit
}) {
return /* html */ `
<!--
* Copyright (c) 2021 GraphQL Contributors
Expand Down Expand Up @@ -39,6 +45,7 @@ export function htmlPage({ endpoint }: { endpoint: string }) {
const root = ReactDOM.createRoot(document.getElementById('graphiql'))
const fetcher = GraphiQL.createFetcher({
url: '${endpoint}',
headers: ${JSON.stringify(headers)}
})
const explorerPlugin = GraphiQLPluginExplorer.explorerPlugin()
root.render(
Expand Down
21 changes: 15 additions & 6 deletions src/graphql/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,38 @@ export function jsonSchemaToSDL(jsonString: string) {

export async function fetchJsonSchema({
url,
headers,
minimal = true
}: {
url: string
headers?: HeadersInit
minimal?: boolean
}): Promise<Json> {
const introspectionOptions = {
descriptions: !minimal,
directiveIsRepeatable: !minimal,
schemaDescription: !minimal
} satisfies IntrospectionOptions

try {
const response = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
...headers
},
body: JSON.stringify({
query: getIntrospectionQuery(introspectionOptions),
variable: {}
variables: {}
})
})

if (!response.ok) throw new Error(`Failed to fetch from ${url}: ${response.statusText}`)

return await response.json()
const json = await response.json()

if (!response.ok) {
throw new Error(`Failed to fetch from ${url} - ${response.statusText}: ${json}`)
}
return json
} catch (error) {
const errorMessage = error instanceof Error ? error.message : `Encoutered an error: ${error}`
console.error(errorMessage)
Expand Down
29 changes: 24 additions & 5 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ import { isURL, formatMessages, LANDING_MESSAGE } from '#/utilities.ts'
* Route: <base-url>/json/<introspection-url> -> JSON schema
* Route: <base-url>/sdl/<introspection-url> -> SDL schema
* Route: <base-url>/playground/<introspection-url> -> GraphQL Playground
*
* Headers
*
* If you need to pass an API key in headers, pass as:
* { "X-API-KEY-NAME": "<api-key-name>", "X-API-KEY-VALUE": "<api-key-value>" }
* Example
* { "X-API-KEY": "Authorization", "X-API-VALUE": "Bearer 1234567890" }
*/
export async function handler(request: Request): Promise<Response> {
try {
Expand All @@ -27,15 +34,27 @@ export async function handler(request: Request): Promise<Response> {
)
}

const apiKeyName = request.headers.get('X-API-KEY-NAME')
const apiKeyValue = request.headers.get('X-API-KEY-VALUE')

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' }
})
return new Response(
htmlPage({
endpoint: introspectionURL,
headers: { [apiKeyName]: apiKeyValue }
}),
{
status: 200,
headers: { 'Content-Type': 'text/html' }
}
)
}

const jsonSchema = await fetchJsonSchema({ url: introspectionURL })
const jsonSchema = await fetchJsonSchema({
url: introspectionURL,
headers: { [apiKeyName]: apiKeyValue }
})

if (requestedFormat === 'sdl') {
const sdlSchema = jsonSchemaToSDL(JSON.stringify(jsonSchema))
Expand Down

0 comments on commit 7faa7a5

Please sign in to comment.