Files
skills/docs/api-stack/api/api-graphql/src/federation/parse-sdl.md
2026-05-29 08:20:56 +01:00

2.5 KiB

parse-sdl

Purpose

Minimal SDL parser used by the federation merger to locate type Name { ... } and extend type Name { ... } blocks plus the field names inside each. This is not a full GraphQL AST parser — it is the contract-layer dependency-free helper that recognises the constructs the federation rules care about (design §10.2).

Engine adapters re-parse the merged SDL with their own AST machinery. The purpose of this parser is the cross-plugin invariant check before the engine ever sees the schema.

Features

  • Recognises type Name { ... } and extend type Name { ... } blocks.
  • Extracts field names (handles inline argument lists field(a: Int): T).
  • Strips line comments (# ...) and block string descriptions ("""...""") before parsing.
  • Ignores union / interface / input / enum / scalar declarations — these pass through to the merged SDL but don't contribute to the field-level collision check.

Usage: Basic

import { parseSdl } from "@suaveplan/api-graphql/federation";

const blocks = parseSdl(
    "type Invoice { id: ID! total: Int! } extend type Query { invoices: [Invoice!]! }"
);
console.log(blocks[0].typeName); // "Invoice"
console.log(blocks[1].kind);     // "extend"
console.log(blocks[1].fields);   // ["invoices"]

Usage: Advanced

Strip descriptions before parsing for downstream tooling that wants only the structural SDL:

import { stripCommentsAndDescriptions } from "@suaveplan/api-graphql/federation";

const cleaned = stripCommentsAndDescriptions(`
    """Invoice domain root"""
    type Invoice {
        # the canonical id
        id: ID!
    }
`);

API Reference

  • parseSdl(sdl) → TypeBlock[] — extract structured blocks.
  • stripCommentsAndDescriptions(sdl) → string — comment + block-string removal.
  • TypeBlock — { kind: "type" | "extend"; typeName; fields; rawBlock }.

Implementation Notes

The parser uses three regexes: one for block-string descriptions, one for line comments, and one for the type/extend block envelope. Field-name extraction is line-oriented; multi-line argument lists fall back to the inline-argument regex, which is ([a-z_][a-z0-9_]*)\s*(?:\([^)]*\))?\s*:.

Pathological inputs (nested braces inside field type expressions, e.g. field: { ... }) are not supported — GraphQL SDL doesn't use them. If a future GraphQL spec extension introduces nested braces, the regex would need replacing with a proper tokeniser; that's a known limit and acceptable for the contract layer.