polen
Version:
A framework for delightful GraphQL developer portals
164 lines (138 loc) ⢠5.18 kB
text/typescript
/**
* Example usage of the GraphQL Document Analysis library
*
* This demonstrates how to use the foundational layer for extracting
* identifiers and context from GraphQL documents - the building block
* for the interactive GraphQL Document Component.
*/
import { GraphQLDocument } from './$.js'
// Example GraphQL query with various constructs
const exampleQuery = `
query GetUserWithProjects($id: ID!, $limit: Int = 10) {
user(id: $id) {
name
projects(first: $limit) {
name
isPrivate
owner {
name
}
}
... on EnterpriseUser {
organization
}
}
}
fragment UserBasics on User {
name
email
role
}
`
/**
* Demonstrate basic analysis
*/
export const analyzeExample = () => {
console.log(`š Analyzing GraphQL Document...\n`)
const result = GraphQLDocument.analyze(exampleQuery)
console.log(`ā
Valid: ${result.isValid}`)
console.log(`š Total identifiers: ${result.identifiers.all.length}`)
console.log(`šØ Errors: ${result.errors.length}\n`)
// Show identifiers by kind
for (const [kind, identifiers] of result.identifiers.byKind) {
console.log(`${getKindEmoji(kind)} ${kind} (${identifiers.length}):`)
for (const identifier of identifiers) {
const pos = `${identifier.position.line}:${identifier.position.column}`
const path = identifier.schemaPath.join(` ā `)
const parent = identifier.parentType ? ` (in ${identifier.parentType})` : ``
console.log(` ⢠${identifier.name}${parent} ā ${path} @ ${pos}`)
}
console.log()
}
return result
}
/**
* Demonstrate identifier lookup by position
*/
export const demonstratePositionLookup = () => {
console.log(`š Position-based Identifier Lookup...\n`)
const identifiers = GraphQLDocument.extractIdentifiers(exampleQuery)
// Find identifier at a specific position (e.g., cursor position in an editor)
const targetPosition = 180 // Approximate position of "abilities" field
// Find the closest identifier to this position
let closestIdentifier = null
let closestDistance = Infinity
for (const identifier of identifiers.all) {
const distance = Math.abs(identifier.position.start - targetPosition)
if (distance < closestDistance) {
closestDistance = distance
closestIdentifier = identifier
}
}
if (closestIdentifier) {
console.log(`šÆ Identifier near position ${targetPosition}:`)
console.log(` Name: ${closestIdentifier.name}`)
console.log(` Kind: ${closestIdentifier.kind}`)
console.log(` Schema Path: ${closestIdentifier.schemaPath.join(` ā `)}`)
console.log(` Context: ${JSON.stringify(closestIdentifier.context, null, 2)}`)
}
}
/**
* Demonstrate how this enables hyperlink generation
*/
export const demonstrateHyperlinkGeneration = () => {
console.log(`š Hyperlink Generation Preview...\n`)
const identifiers = GraphQLDocument.extractIdentifiers(exampleQuery)
// Show how each identifier could become a hyperlink
const typeIdentifiers = identifiers.byKind.get(`Type`) || []
const fieldIdentifiers = identifiers.byKind.get(`Field`) || []
console.log(`š Type References ā Schema Links:`)
for (const identifier of typeIdentifiers) {
const referenceUrl = `/reference/${identifier.name}`
console.log(` ${identifier.name} ā ${referenceUrl}`)
}
console.log(`\nš Field References ā Schema Links:`)
for (const identifier of fieldIdentifiers.slice(0, 5)) { // Show first 5
const referenceUrl = identifier.parentType
? `/reference/${identifier.parentType}#${identifier.name}`
: `/reference/${identifier.name}`
console.log(` ${identifier.name} ā ${referenceUrl}`)
}
}
/**
* Show the foundation for hover tooltips
*/
export const demonstrateTooltipFoundation = () => {
console.log(`š¬ Tooltip Foundation...\n`)
const identifiers = GraphQLDocument.extractIdentifiers(exampleQuery)
// Show context information that would be displayed in tooltips
const fieldIdentifiers = identifiers.byKind.get(`Field`) || []
for (const identifier of fieldIdentifiers.slice(0, 3)) { // Show first 3
console.log(`š·ļø ${identifier.name}:`)
console.log(` Position: Line ${identifier.position.line}, Column ${identifier.position.column}`)
console.log(` Schema Path: ${identifier.schemaPath.join(` ā `)}`)
console.log(` Parent Type: ${identifier.parentType || `Root`}`)
console.log(` Operation: ${identifier.context.operationType || `None`}`)
console.log(` Selection Path: ${identifier.context.selectionPath.join(` ā `)}`)
console.log()
}
}
// Helper function
const getKindEmoji = (kind: string): string => {
const emojis: Record<string, string> = {
'Type': `š·ļø`,
'Field': `š`,
'Argument': `āļø`,
'Variable': `š°`,
'Directive': `šÆ`,
'Fragment': `š§©`,
}
return emojis[kind] || `ā`
}
// Run example if executed directly
if (import.meta.url === `file://${process.argv[1]}`) {
analyzeExample()
demonstratePositionLookup()
demonstrateHyperlinkGeneration()
demonstrateTooltipFoundation()
}