JSPM

@sanity-labs/groq-lsp

1.0.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 83
  • Score
    100M100P100Q78167F
  • License MIT

Language Server Protocol implementation for GROQ

Package Exports

  • @sanity-labs/groq-lsp

Readme

@sanity-labs/groq-lsp

Language Server Protocol (LSP) implementation for GROQ - provides IDE features for GROQ queries in any editor.

Features

Feature Description
Diagnostics Real-time linting via @sanity/groq-lint
Hover Type information and documentation
Completion Field names, functions, document types
Formatting Via prettier-plugin-groq

Installation

npm install @sanity-labs/groq-lsp
# or
pnpm add @sanity-labs/groq-lsp

Usage

As a Language Server (CLI)

Start the server using Node IPC:

npx @sanity-labs/groq-lsp

The server communicates via stdio and can be connected to any LSP-compatible editor.

As a Library

import {
  SchemaLoader,
  extractQueries,
  computeDocumentDiagnostics,
  getCompletions,
  getHoverInfo,
  formatQuery,
} from '@sanity-labs/groq-lsp'

// Load schema
const loader = new SchemaLoader()
loader.loadFromPath('./schema.json')
// Or auto-discover: loader.discoverSchema(workspaceRoot)

// Extract GROQ queries from source file
const { queries } = extractQueries(sourceCode, 'typescript')

// Get diagnostics
const diagnostics = computeDocumentDiagnostics(queries, {
  schema: loader.getSchema(),
})

// Get completions at a position
const completions = getCompletions(query, cursorOffset, {
  schema: loader.getSchema(),
})

// Get hover info at a position
const hover = getHoverInfo(query, cursorOffset, {
  schema: loader.getSchema(),
})

// Format a query
const edits = await formatQuery(query, { tabSize: 2 })

Editor Integration

VS Code

The server is designed to work with VS Code's LSP client. Configure your extension's package.json:

{
  "contributes": {
    "languages": [
      {
        "id": "groq",
        "extensions": [".groq"],
        "aliases": ["GROQ"]
      }
    ]
  }
}

And in your extension code:

import { LanguageClient, TransportKind } from 'vscode-languageclient/node'

const serverModule = require.resolve('@sanity-labs/groq-lsp/dist/server.js')

const client = new LanguageClient(
  'groqLanguageServer',
  'GROQ Language Server',
  {
    run: { module: serverModule, transport: TransportKind.ipc },
    debug: { module: serverModule, transport: TransportKind.ipc },
  },
  {
    documentSelector: [
      { scheme: 'file', language: 'groq' },
      { scheme: 'file', language: 'typescript' },
      { scheme: 'file', language: 'typescriptreact' },
    ],
  }
)

client.start()

Neovim (nvim-lspconfig)

local lspconfig = require('lspconfig')
local configs = require('lspconfig.configs')

if not configs.groq_lsp then
  configs.groq_lsp = {
    default_config = {
      cmd = { 'npx', '@sanity-labs/groq-lsp' },
      filetypes = { 'groq', 'typescript', 'typescriptreact' },
      root_dir = lspconfig.util.root_pattern('schema.json', 'sanity.config.ts'),
    },
  }
end

lspconfig.groq_lsp.setup{}

Schema Discovery

The server automatically searches for schema files in these locations:

  1. schema.json
  2. sanity.schema.json
  3. .sanity/schema.json
  4. studio/schema.json

Generate a schema file from your Sanity project:

npx sanity schema extract --path schema.json

Configuration

The server accepts configuration via the LSP workspace/configuration request:

interface Settings {
  // Path to schema.json file
  schemaPath?: string
  // Maximum number of diagnostics to report (default: 100)
  maxDiagnostics?: number
  // Enable formatting (default: true)
  enableFormatting?: boolean
}

In VS Code, configure via settings.json:

{
  "groq.schemaPath": "./studio/schema.json",
  "groq.maxDiagnostics": 50,
  "groq.enableFormatting": true
}

Supported Languages

The server provides features for:

Language File Types Query Detection
GROQ .groq Entire file
TypeScript .ts, .tsx groq...`` template literals
JavaScript .js, .jsx groq...`` template literals

LSP Capabilities

Diagnostics

Automatically validates GROQ queries on document change:

  • Performance rules - Always enabled (join-in-filter, pagination, etc.)
  • Schema-aware rules - When schema is available (invalid-type-filter, unknown-field)

Completion

Provides intelligent completions based on context:

*[_type == "|"] // Suggests: "post", "author", etc.
*[_type == "post"]{ | } // Suggests: title, body, _id, etc.
cou| // Suggests: count()

Hover

Shows type information and documentation:

_type: string
Document type name

Formatting

Formats GROQ queries using prettier-plugin-groq:

// Before
*[_type=="post"&&published==true]{title,body,...}

// After
*[_type == "post" && published == true] {
  title,
  body,
  ...
}

API Reference

SchemaLoader

Manages schema loading and caching.

const loader = new SchemaLoader()

// Load from specific path
loader.loadFromPath('./schema.json')

// Auto-discover in workspace
loader.discoverSchema('/path/to/workspace')

// Get current schema
const schema = loader.getSchema()

// Watch for changes
loader.startWatching((newSchema) => {
  console.log('Schema updated')
})

// Clean up
loader.stopWatching()
loader.clear()

extractQueries

Extracts GROQ queries from source files.

const { queries, errors } = extractQueries(content, 'typescript')
// Returns: { queries: GroqQuery[], errors: string[] }

computeDocumentDiagnostics

Computes LSP diagnostics for extracted queries.

const diagnostics = computeDocumentDiagnostics(queries, { schema })
// Returns: Diagnostic[]

getCompletions

Gets completion items at a position.

const items = getCompletions(query, cursorOffset, { schema })
// Returns: CompletionItem[]

getHoverInfo

Gets hover information at a position.

const hover = getHoverInfo(query, cursorOffset, { schema })
// Returns: Hover | null

formatQuery / formatDocument

Formats GROQ queries using Prettier.

const edits = await formatQuery(query, { tabSize: 2 })
// Returns: TextEdit[]

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Test
pnpm test

# Watch mode
pnpm dev

License

MIT