# `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 ```ts 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: ```ts 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.