mirror of
https://github.com/supabase/supabase.git
synced 2026-10-11 20:35:07 +03:00
* feat (content api): add top-level schema query
Adds a top-level schema query that returns the stringified GraphQL
schema for this endpoint. Useful for LLMs to access the stringified
schema for prompting and tool calls.
Query shape:
```
query Search {
schema
}
```
Query response:
```
{
"data": {
"schema": "schema {\n query: RootQueryType\n}\n\ntype RootQueryType
{\n \"\"\"Get the GraphQL schema for this endpoint\"\"\"\n schema:
String\n}"
}
}
```
Towards DOCS-214
* test (content api): add schema snapshot
Add schema snapshot test to prevent unintentional changes to public API
for this endpoint
* fixup! feat (content api): add top-level schema query
* fix (content api): local dev introspection
The validation rules that are used for security in production are
preventing GraphiQL from introspecting the schema in dev. Since this DX
feature is incredibly useful, I'm turning off the complexity and depth
validations for dev GraphiQL only. Local curls, etc., will still have
production-standard validation so it can be tested locally.
85 lines
2.5 KiB
TypeScript
85 lines
2.5 KiB
TypeScript
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
|
import { POST } from './route'
|
|
|
|
describe('/api/graphql basic error statuses', () => {
|
|
beforeEach(() => {
|
|
vi.clearAllMocks()
|
|
vi.spyOn(console, 'error').mockImplementation(() => {})
|
|
})
|
|
|
|
it('should return error if request body is not valid JSON', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: 'not json',
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toBe('Invalid request: Request body must be valid JSON')
|
|
})
|
|
|
|
it('should return error if request body is missing required fields', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ variables: {} }),
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toContain(
|
|
'Invalid request: Request body must be valid GraphQL request object'
|
|
)
|
|
})
|
|
|
|
it('should return error if query is not a string', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ query: 123 }),
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toContain(
|
|
'Invalid request: Request body must be valid GraphQL request object'
|
|
)
|
|
})
|
|
|
|
it('should return error for internal server errors', async () => {
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ query: 'query { hello }' }),
|
|
})
|
|
|
|
vi.spyOn(request, 'json').mockImplementation(() => {
|
|
throw new Error('Unexpected error')
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors[0].message).toBe('Internal Server Error')
|
|
})
|
|
})
|
|
|
|
describe('/api/graphql schema snapshot', () => {
|
|
it('should match snapshot', async () => {
|
|
const schemaQuery = `
|
|
query {
|
|
schema
|
|
}
|
|
`
|
|
const request = new Request('http://localhost/api/graphql', {
|
|
method: 'POST',
|
|
body: JSON.stringify({ query: schemaQuery }),
|
|
})
|
|
|
|
const response = await POST(request)
|
|
const json = await response.json()
|
|
expect(json.errors).toBeUndefined()
|
|
|
|
const {
|
|
data: { schema },
|
|
} = json
|
|
expect(schema).toMatchSnapshot()
|
|
})
|
|
})
|