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 { ... }andextend 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.