# `depth-and-complexity.ts` _(no submodules)_ ## Purpose Implements the static depth + complexity guard that the Yoga engine runs after parsing each query and before execution. Documents that exceed the configured limits are rejected with `GRAPHQL_YOGA.DEPTH_EXCEEDED` or `GRAPHQL_YOGA.COMPLEXITY_EXCEEDED`, which lets the host reject denial-of- service payloads (deeply nested fragments, fan-out spreads) before any resolver runs. The guard is intentionally cheap: a single recursive walk over the already-parsed `DocumentNode`, no schema awareness, no cost estimator. Hosts that want a smarter cost model (database joins, external service fan-out) compose a stricter guard on top. ## Features - Tracks deepest `SelectionSet` nesting level per operation. - Counts every `Field` node touched, expanding fragment spreads inline once per occurrence. - Throws subclass `GraphqlYogaError` with `context.depth` / `context.limit` for log-side debugging. ## Usage: Basic ```ts import { parse } from "graphql"; import { enforceGuards } from "@suaveplan/api-graphql-yoga"; const doc = parse("{ ping }"); enforceGuards(doc, { maxDepth: 10, maxComplexity: 1000 }); ``` ## Usage: Advanced ```ts import { parse } from "graphql"; import { enforceGuards } from "@suaveplan/api-graphql-yoga"; const doc = parse(` fragment f on Customer { id name orders { id } } query { customer(id: "c1") { ...f } } `); try { enforceGuards(doc, { maxDepth: 3, maxComplexity: 5 }); } catch (error) { // GRAPHQL_YOGA.DEPTH_EXCEEDED or COMPLEXITY_EXCEEDED } ``` ## API Reference - `enforceGuards(document, { maxDepth, maxComplexity })` — throws on violation, returns `void` on pass. ## Implementation Notes Fragment cycles would cause unbounded recursion if the walker re-visited spreads; in practice the GraphQL `validate()` pass that runs immediately after parsing rejects cycle-containing documents, so the depth/complexity walker can rely on cycle-free input. Should a future change move the guard ahead of validation, add a `Set` of seen spreads to short-circuit.