{"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/depth-limit.ts","../src/depth-engine.ts","../src/directives.ts","../src/ignore.ts","../src/depth-options.ts","../src/operation-names.ts"],"sourcesContent":["/**\n * GraphQL Query Depth Limit — ESM Compatible\n *\n * A validation rule that limits query depth and rejects excessively\n * nested queries before execution.  Works with any GraphQL server.\n *\n * @packageDocumentation\n */\n\n// Exports are sorted by module path (biome's organizeImports rule), not by\n// export name. This is enforced by the linter and is intentional.\nexport { ERROR_CODES } from \"./constants.js\";\nexport { depthLimit } from \"./depth-limit.js\";\nexport { depthDirectiveTypeDefs } from \"./directives.js\";\nexport { isUnsafeRegExp } from \"./ignore.js\";\nexport type {\n\tDepthCallback,\n\tDepthLimitFunction,\n\tDepthLimitOptions,\n\tDirectiveMode,\n\tIgnoreMode,\n\tIgnoreRule,\n\tIntrospectionMode,\n} from \"./types.js\";\n","/**\n * Error extension codes for depth limit violations.\n */\nexport const ERROR_CODES = Object.freeze({\n\tIGNORE_RULE_ERROR: \"IGNORE_RULE_ERROR\",\n\tNODE_LIMIT_EXCEEDED: \"NODE_LIMIT_EXCEEDED\",\n\tQUERY_TOO_DEEP: \"QUERY_TOO_DEEP\",\n} as const);\n","import {\n\ttype ASTVisitor,\n\tGraphQLError,\n\ttype ValidationContext,\n\ttype ValidationRule,\n} from \"graphql\";\n\nimport { ERROR_CODES } from \"./constants.js\";\nimport {\n\tcalculateDepth,\n\tcreateTraversalCaches,\n\textractDefinitions,\n\ttype TraversalConfig,\n} from \"./depth-engine.js\";\nimport {\n\tcreateDepthResultRecord,\n\ttype NormalizedDepthLimitOptions,\n\tnormalizeDepthLimitArgs,\n\tsetDepthResult,\n} from \"./depth-options.js\";\nimport { createOperationNameAllocator } from \"./operation-names.js\";\nimport type { DepthCallback, DepthLimitFunction, DepthLimitOptions } from \"./types.js\";\n\n/**\n * Creates a GraphQL validation rule that limits query depth.\n *\n * Prevents DoS attacks and resource exhaustion from excessively deep queries\n * by enforcing a maximum depth on operations. Supports per-field overrides\n * via the `@depth` directive, customizable ignore rules, and an optional\n * callback for monitoring.\n *\n * Security considerations:\n * - The global `maxDepth` is a hard ceiling by default (`directiveMode: \"cap\"`)\n * - Correctly handles fragments reused at different depths\n * - Circular fragment references are detected per-path\n * - Only `__typename` is ignored by default (`ignoreIntrospection: \"typename\"`)\n * - Short-circuits on first violation when no callback is provided\n *\n * Limitations:\n * - Variables in `@depth` directives are not supported (falls back to global limit)\n * - Field names are case-sensitive by default (use `caseInsensitiveIgnore` if needed)\n * - `useDirective: true` requires a schema in the validation context; without one\n *   it silently falls back to the global limit (directives cannot be resolved)\n *\n * @param maxDepth - Maximum allowed depth for queries (must be a non-negative integer)\n * @param options - Optional configuration for ignore rules, directives, and case sensitivity\n * @param callback - Optional callback invoked with per-operation depths as a plain object payload\n * @returns A GraphQL validation rule function\n * @throws {Error} If `maxDepth` is not a non-negative integer\n *\n * @example\n * ```typescript\n * import { depthLimit } from \"graphql-query-depth-limit-esm\";\n * import { validate } from \"graphql\";\n *\n * const errors = validate(schema, document, [\n *   depthLimit(5, {\n *     ignore: [\"friends\", /.*Connection$/],\n *     useDirective: true,\n *   }),\n * ]);\n *\n * const withCallback = depthLimit(5, (depths) => {\n *   console.log(depths);\n * });\n * ```\n */\nexport function depthLimit(maxDepth: number, callback?: DepthCallback): ValidationRule;\nexport function depthLimit(\n\tmaxDepth: number,\n\toptions?: DepthLimitOptions,\n\tcallback?: DepthCallback,\n): ValidationRule;\nexport function depthLimit(\n\tmaxDepth: number,\n\toptions?: DepthLimitOptions | DepthCallback,\n\tcallback?: DepthCallback,\n): ValidationRule {\n\tif (!Number.isInteger(maxDepth) || maxDepth < 0) {\n\t\tthrow new Error(`Invalid maxDepth: ${maxDepth}. Must be a non-negative integer.`);\n\t}\n\n\tconst normalized = normalizeDepthLimitArgs(options, callback);\n\n\treturn createValidationRule(maxDepth, normalized.options, normalized.callback);\n}\n\n/** Compile-time check that the implementation satisfies the public type. */\ndepthLimit satisfies DepthLimitFunction;\n\n/**\n * Creates the validation rule closure with validated parameters.\n */\nfunction createValidationRule(\n\tmaxDepth: number,\n\toptions?: NormalizedDepthLimitOptions,\n\tcallback?: DepthCallback,\n): ValidationRule {\n\tconst shortCircuit = options?.shortCircuit ?? callback == null;\n\n\treturn function depthLimitValidationRule(context: ValidationContext): ASTVisitor {\n\t\treturn {\n\t\t\t// Report inside the visitor so graphql-js can catch its maxErrors abort.\n\t\t\tDocument() {\n\t\t\t\tconst caches = createTraversalCaches();\n\t\t\t\tconst document = context.getDocument();\n\t\t\t\tconst depths: Record<string, number> | undefined = callback\n\t\t\t\t\t? createDepthResultRecord()\n\t\t\t\t\t: undefined;\n\t\t\t\tconst { fragments, operations } = extractDefinitions(document.definitions);\n\t\t\t\tconst schema = context.getSchema() ?? undefined;\n\t\t\t\t// By design: when useDirective is true but no schema is available,\n\t\t\t\t// directives silently fall back to the global maxDepth. This is not a\n\t\t\t\t// \"silent failure\" - directives cannot be resolved without type info,\n\t\t\t\t// so the global limit is the correct and safe default. Emitting an\n\t\t\t\t// error here would penalize valid schema-less contexts (e.g., custom\n\t\t\t\t// ValidationContext wrappers) where the user intentionally omits the\n\t\t\t\t// schema. See DepthLimitOptions.useDirective JSDoc for documentation.\n\t\t\t\tconst useDirective = Boolean(schema) && (options?.useDirective ?? false);\n\n\t\t\t\tconst nextOperationName = createOperationNameAllocator(operations);\n\n\t\t\t\tconst config: TraversalConfig = {\n\t\t\t\t\tmaxNodes: options?.maxNodes,\n\t\t\t\t\tcaseInsensitiveIgnore: options?.caseInsensitiveIgnore ?? false,\n\t\t\t\t\tdirectiveMode: options?.directiveMode ?? \"cap\",\n\t\t\t\t\tignore: options?.ignore,\n\t\t\t\t\tignoreMode: options?.ignoreMode ?? \"exclude\",\n\t\t\t\t\tintrospectionMode: options?.ignoreIntrospection ?? \"typename\",\n\t\t\t\t\tlimitIgnoredRecursion: options?.limitIgnoredRecursion ?? false,\n\t\t\t\t\tshortCircuit,\n\t\t\t\t\tuseDirective,\n\t\t\t\t};\n\n\t\t\t\tconst rootTypeMap = schema\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tmutation: schema.getMutationType() ?? undefined,\n\t\t\t\t\t\t\tquery: schema.getQueryType() ?? undefined,\n\t\t\t\t\t\t\tsubscription: schema.getSubscriptionType() ?? undefined,\n\t\t\t\t\t\t}\n\t\t\t\t\t: {\n\t\t\t\t\t\t\tmutation: undefined,\n\t\t\t\t\t\t\tquery: undefined,\n\t\t\t\t\t\t\tsubscription: undefined,\n\t\t\t\t\t\t};\n\n\t\t\t\tfor (const operation of operations) {\n\t\t\t\t\tconst operationName = nextOperationName(operation);\n\t\t\t\t\tconst rootType = rootTypeMap[operation.operation];\n\n\t\t\t\t\tlet result: ReturnType<typeof calculateDepth>;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresult = calculateDepth(\n\t\t\t\t\t\t\tcaches,\n\t\t\t\t\t\t\tconfig,\n\t\t\t\t\t\t\tfragments,\n\t\t\t\t\t\t\tmaxDepth,\n\t\t\t\t\t\t\toperation,\n\t\t\t\t\t\t\trootType,\n\t\t\t\t\t\t\tschema,\n\t\t\t\t\t\t);\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tif (error instanceof GraphQLError) {\n\t\t\t\t\t\t\tcontext.reportError(error);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (error instanceof Error && error.name === \"IgnoreRuleError\") {\n\t\t\t\t\t\t\tcontext.reportError(\n\t\t\t\t\t\t\t\tnew GraphQLError(error.message, {\n\t\t\t\t\t\t\t\t\textensions: {\n\t\t\t\t\t\t\t\t\t\tcode: ERROR_CODES.IGNORE_RULE_ERROR,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tnodes: [operation],\n\t\t\t\t\t\t\t\t\toriginalError: error,\n\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow error;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (depths) {\n\t\t\t\t\t\tsetDepthResult(depths, operationName, result.depth);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (result.violation) {\n\t\t\t\t\t\tconst depthValue = result.violation.depth;\n\t\t\t\t\t\tconst depthLabel = shortCircuit ? `at least ${depthValue}` : `${depthValue}`;\n\t\t\t\t\t\tconst violationPath = result.violation.path;\n\t\t\t\t\t\tconst pathSuffix = violationPath.length > 0 ? ` (at ${violationPath.join(\".\")})` : \"\";\n\n\t\t\t\t\t\tcontext.reportError(\n\t\t\t\t\t\t\tnew GraphQLError(\n\t\t\t\t\t\t\t\t`'${operationName}' has depth ${depthLabel} which exceeds maximum allowed depth of ${result.violation.maxDepth}${pathSuffix}`,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\textensions: {\n\t\t\t\t\t\t\t\t\t\tcode: ERROR_CODES.QUERY_TOO_DEEP,\n\t\t\t\t\t\t\t\t\t\tdepth: depthValue,\n\t\t\t\t\t\t\t\t\t\tmaxDepth: result.violation.maxDepth,\n\t\t\t\t\t\t\t\t\t\tpath: violationPath,\n\t\t\t\t\t\t\t\t\t\tshortCircuit,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tnodes: result.violation.node ? [operation, result.violation.node] : [operation],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (callback && depths) {\n\t\t\t\t\t// Keep callback payload as a plain object for compatibility.\n\t\t\t\t\tcallback({ ...depths });\n\t\t\t\t}\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t};\n\t};\n}\n","import {\n\ttype ASTNode,\n\ttype DefinitionNode,\n\ttype FragmentDefinitionNode,\n\tGraphQLError,\n\ttype GraphQLField,\n\ttype GraphQLInterfaceType,\n\ttype GraphQLObjectType,\n\ttype GraphQLOutputType,\n\ttype GraphQLSchema,\n\tgetNamedType,\n\tisCompositeType,\n\tisInterfaceType,\n\tisObjectType,\n\tKind,\n\ttype OperationDefinitionNode,\n\ttype SelectionNode,\n} from \"graphql\";\nimport { ERROR_CODES } from \"./constants.js\";\nimport { getDepthFromDirective } from \"./directives.js\";\nimport { shouldIgnoreField } from \"./ignore.js\";\nimport type { DirectiveMode, IgnoreMode, IgnoreRule, IntrospectionMode } from \"./types.js\";\n\n/**\n * Result returned by the depth calculation engine.\n */\ninterface DepthResult {\n\t/** Maximum depth found across all branches */\n\tdepth: number;\n\t/** Deepest violation found, or `null` if within limits */\n\tviolation: DepthViolation | null;\n}\n\n/**\n * Records a depth limit violation with the offending depth and its limit.\n */\ninterface DepthViolation {\n\t/** The actual depth that exceeded the limit */\n\tdepth: number;\n\t/** The maximum allowed depth that was exceeded */\n\tmaxDepth: number;\n\t/** The AST node that caused the violation, for precise error locations */\n\tnode?: ASTNode;\n\t/** Field path from the operation root to the violation point */\n\tpath: string[];\n}\n\n/**\n * Result of resolving a `@depth` directive on a field definition.\n * @internal\n */\ninterface DirectiveResolution {\n\t/** Whether a directive limit is now active on this path */\n\thasDirectiveLimit: boolean;\n\t/** The resolved maximum depth for this branch */\n\tmaxDepth: number;\n}\n\n/**\n * Lightweight linked-list node for building field paths without per-field\n * array allocations. Only materialized into `string[]` when reporting a\n * violation or populating callback results.\n * @internal\n */\ninterface PathNode {\n\t/** Parent node in the path, or `undefined` for the root */\n\tparent: PathNode | undefined;\n\t/** Field name or alias for this path segment */\n\tsegment: string;\n}\n\n/**\n * Single unit of work on the iterative DFS stack.\n * @internal\n */\ninterface StackFrame {\n\tselectionIndex: number;\n\t/** Current depth at this point in traversal */\n\tcurrentDepth: number;\n\t/** Whether a `@depth` directive has already constrained this path */\n\thasDirectiveLimit: boolean;\n\t/** Ignored field names seen on the current path (for recursion guard) */\n\tignoredFieldsOnPath: Set<string>;\n\t/** Maximum allowed depth for this branch */\n\tmaxDepth: number;\n\t/** The AST node whose selectionSet should be processed */\n\tnode: ASTNode & { selectionSet?: { selections: readonly SelectionNode[] } };\n\t/** Parent type for field resolution */\n\tparentType: GraphQLOutputType | undefined;\n\t/** Linked-list path from the operation root to this node */\n\tpath: PathNode | undefined;\n\t/** Fragment names visited on the current path (for cycle detection) */\n\tvisitedFragments: Set<string>;\n}\n\n/**\n * Caches shared across all stack frames during a single validation run\n * to avoid repeated interface graph walks and directive AST lookups.\n * @internal\n */\ninterface TraversalCaches {\n\t/** Cached raw directive depth per `typeName:fieldName` */\n\tdirectiveDepths: Map<string, number | undefined>;\n\t/** Cached interface lists per type name */\n\tinterfaces: Map<string, GraphQLInterfaceType[]>;\n}\n\n/**\n * Immutable configuration shared across all stack frames during traversal.\n * @internal\n */\ninterface TraversalConfig {\n\tmaxNodes?: number;\n\t/** Whether to use case-insensitive matching for string ignore rules */\n\tcaseInsensitiveIgnore: boolean;\n\t/** Controls how `@depth` directives interact with the global `maxDepth` */\n\tdirectiveMode: DirectiveMode;\n\t/** Rules for fields to ignore in depth calculation */\n\tignore: IgnoreRule[] | undefined;\n\t/** Controls how ignored fields affect depth traversal */\n\tignoreMode: IgnoreMode;\n\t/** Controls which introspection fields are ignored */\n\tintrospectionMode: IntrospectionMode;\n\t/** Whether repeated ignored fields on a path should increment depth */\n\tlimitIgnoredRecursion: boolean;\n\t/** Whether to bail immediately on violation (when no callback needs true depth) */\n\tshortCircuit: boolean;\n\t/** Whether to check for `@depth` directives on fields */\n\tuseDirective: boolean;\n}\n\n/**\n * Calculates the depth of a GraphQL query AST node using iterative DFS.\n *\n * Handles three selection types:\n * - **Fields**: Increment depth by 1 for composite (non-scalar) fields\n * - **Fragment spreads**: Expand the fragment in-place (no depth increment)\n * - **Inline fragments**: Process in-place (no depth increment)\n *\n * Fragment cycle detection uses per-path visited sets so that the same\n * fragment reused at different depths is calculated correctly.\n *\n * When `shortCircuit` is enabled (no callback), the engine bails immediately\n * on the first violation instead of traversing the full subtree.\n *\n * Uses an explicit stack instead of recursion to prevent stack overflow\n * on deeply nested queries.\n *\n * @param caches - Shared caches for interface and directive lookups\n * @param config - Immutable traversal configuration\n * @param fragments - Map of all fragment definitions in the document\n * @param maxDepth - Maximum allowed depth for this branch\n * @param node - The AST node to calculate depth for\n * @param parentType - Root type for field resolution\n * @param schema - GraphQL schema for type resolution\n * @returns The maximum depth and the deepest violation found\n */\nfunction calculateDepth(\n\tcaches: TraversalCaches,\n\tconfig: TraversalConfig,\n\tfragments: Map<string, FragmentDefinitionNode>,\n\tmaxDepth: number,\n\tnode: ASTNode & { selectionSet?: { selections: readonly SelectionNode[] } },\n\tparentType: GraphQLOutputType | undefined,\n\tschema: GraphQLSchema | undefined,\n): DepthResult {\n\tlet deepestViolation: DepthViolation | null = null;\n\tlet globalMaxDepth = 0;\n\tlet nodeCount = 0;\n\n\tif (!node.selectionSet) {\n\t\treturn { depth: 0, violation: null };\n\t}\n\n\tconst stack: StackFrame[] = [\n\t\t{\n\t\t\tselectionIndex: 0,\n\t\t\tcurrentDepth: 0,\n\t\t\thasDirectiveLimit: false,\n\t\t\tignoredFieldsOnPath: new Set<string>(),\n\t\t\tmaxDepth,\n\t\t\tnode,\n\t\t\tparentType,\n\t\t\tpath: undefined,\n\t\t\tvisitedFragments: new Set<string>(),\n\t\t},\n\t];\n\n\tfor (let frame = stack.pop(); frame !== undefined; frame = stack.pop()) {\n\t\tconst selections = frame.node.selectionSet?.selections;\n\t\tif (!selections) continue;\n\t\tconst selection = selections[frame.selectionIndex++];\n\t\tif (!selection) continue;\n\t\t// Resume siblings after this selection's subtree, without retaining exhausted frames.\n\t\tif (frame.selectionIndex < selections.length) stack.push(frame);\n\t\t// Bound fragment expansion even when every branch stays below maxDepth.\n\t\tif (++nodeCount > (config.maxNodes ?? 10_000)) {\n\t\t\tthrow new GraphQLError(\"Query exceeds maximum expanded node limit.\", {\n\t\t\t\tnodes: [selection],\n\t\t\t\textensions: {\n\t\t\t\t\tcode: ERROR_CODES.NODE_LIMIT_EXCEEDED,\n\t\t\t\t\tmaxNodes: config.maxNodes ?? 10_000,\n\t\t\t\t\tnodeCount,\n\t\t\t\t},\n\t\t\t});\n\t\t}\n\t\tswitch (selection.kind) {\n\t\t\tcase Kind.FIELD: {\n\t\t\t\tconst fieldName = selection.name.value;\n\t\t\t\tconst isIntrospectionField = fieldName.startsWith(\"__\");\n\n\t\t\t\t// When introspection is fully ignored, always skip the subtree\n\t\t\t\t// regardless of ignoreMode.\n\t\t\t\tif (config.introspectionMode === \"all\" && isIntrospectionField) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Leaf fields (no selectionSet) never contribute to depth,\n\t\t\t\t// so skip them before running ignore rules to avoid unnecessary\n\t\t\t\t// predicate evaluation and potential errors on irrelevant fields.\n\t\t\t\tif (!selection.selectionSet) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst isIgnored = shouldIgnoreField(\n\t\t\t\t\tfieldName,\n\t\t\t\t\tconfig.ignore,\n\t\t\t\t\tconfig.caseInsensitiveIgnore,\n\t\t\t\t\tconfig.introspectionMode,\n\t\t\t\t);\n\n\t\t\t\tif (isIgnored && config.ignoreMode === \"skip\") {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Resolve field type and directive depth\n\t\t\t\tlet fieldMaxDepth = frame.maxDepth;\n\t\t\t\tlet fieldType: GraphQLOutputType | undefined;\n\t\t\t\tlet hasDirectiveLimit = frame.hasDirectiveLimit;\n\n\t\t\t\tif (schema && frame.parentType) {\n\t\t\t\t\tconst namedType = getNamedType(frame.parentType);\n\t\t\t\t\tif (isObjectType(namedType) || isInterfaceType(namedType)) {\n\t\t\t\t\t\tconst fieldDef = namedType.getFields()[fieldName];\n\t\t\t\t\t\tif (fieldDef) {\n\t\t\t\t\t\t\tfieldType = fieldDef.type;\n\n\t\t\t\t\t\t\t// Defensively skip non-composite fields that erroneously\n\t\t\t\t\t\t\t// have selections (normally caught by GraphQL's own\n\t\t\t\t\t\t\t// validation rules, but guards against miscounted depth\n\t\t\t\t\t\t\t// when this rule runs standalone or before other rules).\n\t\t\t\t\t\t\tconst resolvedType = getNamedType(fieldType);\n\t\t\t\t\t\t\tif (resolvedType && !isCompositeType(resolvedType)) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (config.useDirective) {\n\t\t\t\t\t\t\t\tconst resolved = resolveFieldDirectiveDepth(\n\t\t\t\t\t\t\t\t\tcaches,\n\t\t\t\t\t\t\t\t\tconfig,\n\t\t\t\t\t\t\t\t\tframe.currentDepth,\n\t\t\t\t\t\t\t\t\tframe.maxDepth,\n\t\t\t\t\t\t\t\t\tfieldDef,\n\t\t\t\t\t\t\t\t\tframe.hasDirectiveLimit,\n\t\t\t\t\t\t\t\t\tnamedType,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tfieldMaxDepth = resolved.maxDepth;\n\t\t\t\t\t\t\t\thasDirectiveLimit = resolved.hasDirectiveLimit;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Determine whether this ignored field should still increment\n\t\t\t\t// depth due to the recursion guard detecting repeated ignores\n\t\t\t\t// on the same path. The key is type-aware (`Type:field`) when\n\t\t\t\t// a schema is present so identically named fields on unrelated\n\t\t\t\t// types are tracked independently. Without a schema, the key\n\t\t\t\t// uses the field name alone, which may cause conservative\n\t\t\t\t// over-counting on paths with same-named fields on different types.\n\t\t\t\tlet ignoredFieldsOnPath = frame.ignoredFieldsOnPath;\n\t\t\t\tlet effectivelyIgnored = isIgnored;\n\n\t\t\t\tif (isIgnored && config.limitIgnoredRecursion) {\n\t\t\t\t\tconst parentName = frame.parentType ? getNamedType(frame.parentType)?.name : undefined;\n\t\t\t\t\tconst recursionKey = parentName ? `${parentName}:${fieldName}` : fieldName;\n\n\t\t\t\t\tif (ignoredFieldsOnPath.has(recursionKey)) {\n\t\t\t\t\t\t// Same type:field was already ignored on this path - increment depth\n\t\t\t\t\t\teffectivelyIgnored = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// First occurrence - track it for subsequent path segments\n\t\t\t\t\t\tignoredFieldsOnPath = new Set(ignoredFieldsOnPath);\n\t\t\t\t\t\tignoredFieldsOnPath.add(recursionKey);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst newDepth = effectivelyIgnored ? frame.currentDepth : frame.currentDepth + 1;\n\n\t\t\t\t// Use alias for path (matches the response shape clients see),\n\t\t\t\t// while fieldName is used for schema lookups and ignore rules.\n\t\t\t\tconst pathSegment = selection.alias?.value ?? fieldName;\n\t\t\t\tconst fieldPath = pathPush(frame.path, pathSegment);\n\n\t\t\t\t// Track maximum depth found\n\t\t\t\tif (newDepth > globalMaxDepth) {\n\t\t\t\t\tglobalMaxDepth = newDepth;\n\t\t\t\t}\n\n\t\t\t\t// Check for violation\n\t\t\t\tif (newDepth > fieldMaxDepth) {\n\t\t\t\t\tconst violation: DepthViolation = {\n\t\t\t\t\t\tdepth: newDepth,\n\t\t\t\t\t\tmaxDepth: fieldMaxDepth,\n\t\t\t\t\t\tnode: selection,\n\t\t\t\t\t\tpath: pathToArray(fieldPath),\n\t\t\t\t\t};\n\n\t\t\t\t\tif (config.shortCircuit) {\n\t\t\t\t\t\treturn { depth: newDepth, violation };\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!deepestViolation || violation.depth > deepestViolation.depth) {\n\t\t\t\t\t\tdeepestViolation = violation;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tstack.push({\n\t\t\t\t\tselectionIndex: 0,\n\t\t\t\t\tcurrentDepth: newDepth,\n\t\t\t\t\thasDirectiveLimit,\n\t\t\t\t\tignoredFieldsOnPath,\n\t\t\t\t\tmaxDepth: fieldMaxDepth,\n\t\t\t\t\tnode: selection,\n\t\t\t\t\tparentType: fieldType,\n\t\t\t\t\tpath: fieldPath,\n\t\t\t\t\tvisitedFragments: frame.visitedFragments,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase Kind.FRAGMENT_SPREAD: {\n\t\t\t\tconst fragmentName = selection.name.value;\n\n\t\t\t\t// Check membership before copying to avoid wasted allocations\n\t\t\t\t// when the fragment was already visited on this path.\n\t\t\t\tif (frame.visitedFragments.has(fragmentName)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tconst fragment = fragments.get(fragmentName);\n\t\t\t\tif (!fragment) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Create independent copy for per-path cycle detection\n\t\t\t\tconst fragmentVisited = new Set(frame.visitedFragments);\n\t\t\t\tfragmentVisited.add(fragmentName);\n\n\t\t\t\tconst parentType = fragment.typeCondition\n\t\t\t\t\t? resolveTypeCondition(fragment.typeCondition.name.value, schema, frame.parentType)\n\t\t\t\t\t: frame.parentType;\n\n\t\t\t\tstack.push({\n\t\t\t\t\tselectionIndex: 0,\n\t\t\t\t\tcurrentDepth: frame.currentDepth,\n\t\t\t\t\thasDirectiveLimit: frame.hasDirectiveLimit,\n\t\t\t\t\tignoredFieldsOnPath: frame.ignoredFieldsOnPath,\n\t\t\t\t\tmaxDepth: frame.maxDepth,\n\t\t\t\t\tnode: fragment,\n\t\t\t\t\tparentType,\n\t\t\t\t\tpath: frame.path,\n\t\t\t\t\tvisitedFragments: fragmentVisited,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase Kind.INLINE_FRAGMENT: {\n\t\t\t\tconst parentType = selection.typeCondition\n\t\t\t\t\t? resolveTypeCondition(selection.typeCondition.name.value, schema, frame.parentType)\n\t\t\t\t\t: frame.parentType;\n\n\t\t\t\tstack.push({\n\t\t\t\t\tselectionIndex: 0,\n\t\t\t\t\tcurrentDepth: frame.currentDepth,\n\t\t\t\t\thasDirectiveLimit: frame.hasDirectiveLimit,\n\t\t\t\t\tignoredFieldsOnPath: frame.ignoredFieldsOnPath,\n\t\t\t\t\tmaxDepth: frame.maxDepth,\n\t\t\t\t\tnode: selection,\n\t\t\t\t\tparentType,\n\t\t\t\t\tpath: frame.path,\n\t\t\t\t\tvisitedFragments: frame.visitedFragments,\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck: never = selection;\n\t\t\t\tthrowUnhandledSelectionKind(exhaustiveCheck);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { depth: globalMaxDepth, violation: deepestViolation };\n}\n\n/**\n * Throws for impossible selection kinds. This should only run when a\n * malformed or manually constructed AST bypasses GraphQL parser guarantees.\n */\nfunction throwUnhandledSelectionKind(selection: SelectionNode): never {\n\tthrow new Error(`Unhandled selection kind: ${selection.kind}`);\n}\n\n/**\n * Collects all interfaces implemented by a type, including transitively\n * inherited interfaces (interface-implements-interface chains).\n *\n * @param type - The object or interface type to collect interfaces from\n * @returns All directly and transitively implemented interfaces\n */\nfunction collectInterfaces(type: GraphQLInterfaceType | GraphQLObjectType): GraphQLInterfaceType[] {\n\tconst interfaces: GraphQLInterfaceType[] = [];\n\tconst seen = new Set<string>();\n\tconst stack = [...type.getInterfaces()];\n\n\tfor (let iface = stack.pop(); iface !== undefined; iface = stack.pop()) {\n\t\tif (seen.has(iface.name)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tseen.add(iface.name);\n\t\tinterfaces.push(iface);\n\n\t\tfor (const parent of iface.getInterfaces()) {\n\t\t\tif (!seen.has(parent.name)) {\n\t\t\t\tstack.push(parent);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn interfaces;\n}\n\n/**\n * Creates empty traversal caches for a new validation run.\n *\n * @returns Fresh caches for interface and directive lookups\n */\nfunction createTraversalCaches(): TraversalCaches {\n\treturn {\n\t\tdirectiveDepths: new Map<string, number | undefined>(),\n\t\tinterfaces: new Map<string, GraphQLInterfaceType[]>(),\n\t};\n}\n\n/**\n * Extracts all fragment and operation definitions from a GraphQL document\n * in a single pass.\n *\n * **By design:** Duplicate fragment names are silently overwritten (last wins)\n * rather than raising a validation error. This is intentional - detecting\n * duplicates is the responsibility of GraphQL's built-in `UniqueFragmentNamesRule`,\n * not a depth-limiting rule. When both rules run together (the normal case),\n * duplicates are already caught before this code executes. When used standalone,\n * last-wins is a safe, deterministic fallback that avoids coupling depth\n * validation to fragment uniqueness concerns.\n *\n * @param definitions - Array of definition nodes from the parsed document\n * @returns Fragment map and operation array\n */\nfunction extractDefinitions(definitions: readonly DefinitionNode[]): {\n\tfragments: Map<string, FragmentDefinitionNode>;\n\toperations: OperationDefinitionNode[];\n} {\n\tconst fragments = new Map<string, FragmentDefinitionNode>();\n\tconst operations: OperationDefinitionNode[] = [];\n\n\tfor (const definition of definitions) {\n\t\tif (definition.kind === Kind.FRAGMENT_DEFINITION) {\n\t\t\tfragments.set(definition.name.value, definition);\n\t\t} else if (definition.kind === Kind.OPERATION_DEFINITION) {\n\t\t\toperations.push(definition);\n\t\t}\n\t}\n\n\treturn { fragments, operations };\n}\n\n/**\n * Returns cached interfaces for a type, computing and caching on first access.\n *\n * @param caches - Traversal caches\n * @param type - The object or interface type to get interfaces for\n * @returns All directly and transitively implemented interfaces\n */\nfunction getCachedInterfaces(\n\tcaches: TraversalCaches,\n\ttype: GraphQLInterfaceType | GraphQLObjectType,\n): GraphQLInterfaceType[] {\n\tconst cached = caches.interfaces.get(type.name);\n\tif (cached !== undefined) {\n\t\treturn cached;\n\t}\n\n\tconst result = collectInterfaces(type);\n\tcaches.interfaces.set(type.name, result);\n\treturn result;\n}\n\n/**\n * Creates a new path node by appending a segment to the parent path.\n *\n * @param parent - Parent path node, or `undefined` for the root\n * @param segment - Field name or alias for this path segment\n * @returns New path node linked to the parent\n */\nfunction pathPush(parent: PathNode | undefined, segment: string): PathNode {\n\treturn { parent, segment };\n}\n\n/**\n * Materializes a linked-list path into a string array.\n *\n * @param node - Leaf path node to materialize from\n * @returns Array of path segments from root to leaf\n */\nfunction pathToArray(node: PathNode | undefined): string[] {\n\tconst result: string[] = [];\n\tlet current = node;\n\twhile (current) {\n\t\tresult.push(current.segment);\n\t\tcurrent = current.parent;\n\t}\n\tresult.reverse();\n\treturn result;\n}\n\n/**\n * Resolves a `@depth` directive on a field definition, falling back to\n * interface field directives when the concrete field has none.\n *\n * **Precedence:** The concrete field's directive takes priority. Interface\n * directives are only consulted when the concrete field has no `@depth`.\n * When multiple interfaces define `@depth` on the same field, the strictest\n * (minimum) value wins.\n *\n * Results are memoized per `typeName:fieldName` in the traversal caches\n * to avoid repeated interface graph walks on large schemas.\n *\n * @param caches - Traversal caches for memoizing lookups\n * @param config - Traversal configuration\n * @param currentDepth - Current depth in the query tree\n * @param currentMaxDepth - Current maximum depth for this branch\n * @param fieldDef - The field definition to inspect\n * @param hasDirectiveLimit - Whether a directive has already constrained this path\n * @param namedType - The named parent type owning this field (already unwrapped)\n * @returns Resolved maximum depth and directive limit state\n */\nfunction resolveFieldDirectiveDepth(\n\tcaches: TraversalCaches,\n\tconfig: TraversalConfig,\n\tcurrentDepth: number,\n\tcurrentMaxDepth: number,\n\tfieldDef: GraphQLField<unknown, unknown>,\n\thasDirectiveLimit: boolean,\n\tnamedType: GraphQLInterfaceType | GraphQLObjectType,\n): DirectiveResolution {\n\tconst cacheKey = `${namedType.name}:${fieldDef.name}`;\n\n\tlet directiveDepth: number | undefined;\n\n\tif (caches.directiveDepths.has(cacheKey)) {\n\t\tdirectiveDepth = caches.directiveDepths.get(cacheKey);\n\t} else {\n\t\tdirectiveDepth = getDepthFromDirective(fieldDef);\n\n\t\tif (directiveDepth === undefined) {\n\t\t\tconst interfaces = getCachedInterfaces(caches, namedType);\n\t\t\tfor (const iface of interfaces) {\n\t\t\t\tconst ifaceField = iface.getFields()[fieldDef.name];\n\t\t\t\tconst ifaceDepth = getDepthFromDirective(ifaceField);\n\t\t\t\tif (ifaceDepth !== undefined) {\n\t\t\t\t\tdirectiveDepth =\n\t\t\t\t\t\tdirectiveDepth === undefined ? ifaceDepth : Math.min(directiveDepth, ifaceDepth);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcaches.directiveDepths.set(cacheKey, directiveDepth);\n\t}\n\n\tif (directiveDepth !== undefined) {\n\t\tconst relativeMax = currentDepth + directiveDepth;\n\t\tconst maxDepth =\n\t\t\tconfig.directiveMode === \"cap\"\n\t\t\t\t? Math.min(currentMaxDepth, relativeMax)\n\t\t\t\t: hasDirectiveLimit\n\t\t\t\t\t? Math.min(currentMaxDepth, relativeMax)\n\t\t\t\t\t: relativeMax;\n\t\treturn { hasDirectiveLimit: true, maxDepth };\n\t}\n\n\treturn { hasDirectiveLimit, maxDepth: currentMaxDepth };\n}\n\n/**\n * Resolves the parent type from a type condition on a fragment or inline fragment.\n *\n * Falls back to `currentParentType` when the schema is unavailable or the\n * type condition resolves to a non-composite type (which GraphQL's own\n * validation would reject, but is handled defensively here).\n *\n * @param typeConditionName - The name of the type condition\n * @param schema - GraphQL schema for type lookup\n * @param currentParentType - Fallback parent type if resolution fails\n * @returns The resolved composite type or the current parent type\n */\nfunction resolveTypeCondition(\n\ttypeConditionName: string,\n\tschema: GraphQLSchema | undefined,\n\tcurrentParentType: GraphQLOutputType | undefined,\n): GraphQLOutputType | undefined {\n\tif (schema) {\n\t\tconst type = schema.getType(typeConditionName);\n\t\tif (type && isCompositeType(type)) {\n\t\t\treturn type;\n\t\t}\n\t}\n\treturn currentParentType;\n}\n\nexport type { DepthResult, TraversalCaches, TraversalConfig };\nexport { calculateDepth, createTraversalCaches, extractDefinitions };\n","import { type GraphQLField, Kind } from \"graphql\";\n\n/**\n * GraphQL SDL type definition for the `@depth` directive.\n *\n * Include this in your schema definition to enable per-field depth\n * overrides when using `depthLimit` with `{ useDirective: true }`.\n *\n * @example\n * ```ts\n * import { makeExecutableSchema } from \"@graphql-tools/schema\";\n * import { depthDirectiveTypeDefs } from \"graphql-query-depth-limit-esm\";\n *\n * const schema = makeExecutableSchema({\n *   typeDefs: [depthDirectiveTypeDefs, yourTypeDefs],\n *   resolvers,\n * });\n * ```\n */\nexport const depthDirectiveTypeDefs = /* GraphQL */ `directive @depth(max: Int!) on FIELD_DEFINITION`;\n\n/**\n * Extracts the maximum depth from a `@depth(max: Int!)` directive on a field definition.\n *\n * Only integer literals are supported. Variables (e.g., `@depth(max: $var)`) are not\n * supported because variable values are unavailable during the validation phase.\n * Fields with variable-based directives fall back to the global depth limit.\n *\n * @param field - The GraphQL field definition to inspect\n * @returns The maximum depth from the directive, or `undefined` if not found or invalid\n *\n * @example\n * ```graphql\n * type Query {\n *   users: [User!]! @depth(max: 3)\n * }\n * ```\n */\nexport function getDepthFromDirective(\n\tfield: GraphQLField<unknown, unknown> | undefined,\n): number | undefined {\n\tif (!field?.astNode?.directives) {\n\t\treturn undefined;\n\t}\n\n\tconst depthDirective = field.astNode.directives.find((d) => d.name.value === \"depth\");\n\n\tif (!depthDirective?.arguments) {\n\t\treturn undefined;\n\t}\n\n\tconst maxArg = depthDirective.arguments.find((arg) => arg.name.value === \"max\");\n\n\tif (maxArg?.value.kind === Kind.INT) {\n\t\tconst directiveDepth = Number.parseInt(maxArg.value.value, 10);\n\t\tif (Number.isFinite(directiveDepth) && directiveDepth >= 0) {\n\t\t\treturn directiveDepth;\n\t\t}\n\t}\n\n\treturn undefined;\n}\n","import type { IgnoreRule, IntrospectionMode } from \"./types.js\";\n\n/**\n * Quantifier characters that indicate repetition in a regex pattern.\n * Used by {@link isUnsafeRegExp} to detect nested quantifier structures.\n */\nconst QUANTIFIER_CHARS = new Set([\"+\", \"*\", \"?\"]);\n\n/**\n * Pattern that matches a `{n,m}` style quantifier at a given position.\n * Captures groups: `{min,}`, `{min,max}`, or `{n}` where `min > 1`.\n */\nconst BRACE_QUANTIFIER = /^\\{(\\d+)(?:,(\\d*))?\\}/;\n\n/**\n * Detects whether a `RegExp` is potentially vulnerable to catastrophic\n * backtracking (ReDoS).\n *\n * Uses lightweight static analysis on the pattern source to identify\n * two common ReDoS structures:\n *\n * 1. **Nested quantifiers** — A quantified group containing a quantified\n *    sub-expression (e.g., `(a+)+`, `(a*)*`, `(a+)*`, `(a{2,})+`).\n * 2. **Overlapping alternation under a quantifier** — A quantified group\n *    whose alternatives can match the same input (e.g., `(a|a)+`,\n *    `(\\w|\\d)+`).\n *\n * This is a heuristic — it may reject some safe patterns and miss some\n * unsafe ones. The goal is to catch the most common footguns without\n * requiring a full regex parser.\n *\n * @param regex - The `RegExp` to analyze\n * @returns A descriptive reason string if the pattern is potentially\n *          unsafe, or `null` if no issues are detected\n *\n * @example\n * ```typescript\n * isUnsafeRegExp(/(a+)+$/);    // \"nested quantifier: group with inner quantifier followed by outer quantifier\"\n * isUnsafeRegExp(/^internal/); // null (safe)\n * ```\n */\nexport function isUnsafeRegExp(regex: RegExp): string | null {\n\tconst source = regex.source;\n\tconst length = source.length;\n\n\t// Track group nesting and whether any group contains a quantifier\n\tconst groupStack: boolean[] = [];\n\n\tfor (let i = 0; i < length; i++) {\n\t\tconst char = source.charAt(i);\n\n\t\t// Skip escaped characters\n\t\tif (char === \"\\\\\") {\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Skip character classes entirely — quantifiers inside [...] are literals\n\t\tif (char === \"[\") {\n\t\t\twhile (i < length && source[i] !== \"]\") {\n\t\t\t\tif (source[i] === \"\\\\\") i++;\n\t\t\t\ti++;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Opening group (capturing or non-capturing)\n\t\tif (char === \"(\") {\n\t\t\tgroupStack.push(false);\n\t\t\t// Skip non-capturing/lookahead syntax: (?:, (?=, (?!, (?<=, (?<!\n\t\t\t// so the `?` is not misinterpreted as a quantifier on the `(`.\n\t\t\tif (source[i + 1] === \"?\") {\n\t\t\t\ti++;\n\t\t\t\tif (source[i + 1] === \"<\" && (source[i + 2] === \"=\" || source[i + 2] === \"!\")) {\n\t\t\t\t\ti += 2;\n\t\t\t\t} else if (source[i + 1] === \":\" || source[i + 1] === \"=\" || source[i + 1] === \"!\") {\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Closing group — check if followed by a quantifier\n\t\tif (char === \")\") {\n\t\t\tconst groupHadQuantifier = groupStack.pop() ?? false;\n\n\t\t\tif (groupHadQuantifier && isFollowedByQuantifier(source, i + 1, length)) {\n\t\t\t\treturn \"nested quantifier: group with inner quantifier followed by outer quantifier\";\n\t\t\t}\n\n\t\t\t// Mark the parent group as containing a quantifier if this group is quantified\n\t\t\tif (groupStack.length > 0 && isFollowedByQuantifier(source, i + 1, length)) {\n\t\t\t\tgroupStack[groupStack.length - 1] = true;\n\t\t\t}\n\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Detect quantifiers on non-group atoms and mark the parent group\n\t\tif (QUANTIFIER_CHARS.has(char) || char === \"{\") {\n\t\t\tif (char === \"{\") {\n\t\t\t\tconst match = BRACE_QUANTIFIER.exec(source.slice(i));\n\t\t\t\tif (!match) continue;\n\n\t\t\t\tconst minStr = match[1] ?? \"0\";\n\t\t\t\tconst min = Number.parseInt(minStr, 10);\n\t\t\t\tconst fullMatch = match[0] ?? \"\";\n\t\t\t\tconst hasComma = fullMatch.includes(\",\");\n\n\t\t\t\t// {0} and {1} are not meaningful quantifiers for ReDoS\n\t\t\t\tif (!hasComma && min <= 1) continue;\n\t\t\t\t// {0,0} and {0,1} ({1} equivalent to ?) are borderline — skip\n\t\t\t\tif (\n\t\t\t\t\thasComma &&\n\t\t\t\t\tmatch[2] !== undefined &&\n\t\t\t\t\tmatch[2] !== \"\" &&\n\t\t\t\t\tNumber.parseInt(match[2], 10) <= 1\n\t\t\t\t)\n\t\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (groupStack.length > 0) {\n\t\t\t\tgroupStack[groupStack.length - 1] = true;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Checks if the character at `pos` starts a quantifier (`+`, `*`, `?`, `{n,m}`).\n */\nfunction isFollowedByQuantifier(source: string, pos: number, length: number): boolean {\n\tif (pos >= length) return false;\n\n\tconst char = source[pos];\n\tif (char === \"+\" || char === \"*\") return true;\n\tif (char === \"{\") {\n\t\tconst match = BRACE_QUANTIFIER.exec(source.slice(pos));\n\t\tif (match) {\n\t\t\tconst minStr = match[1] ?? \"0\";\n\t\t\tconst min = Number.parseInt(minStr, 10);\n\t\t\tconst fullMatch = match[0] ?? \"\";\n\t\t\tconst hasComma = fullMatch.includes(\",\");\n\t\t\tif (!hasComma && min <= 1) return false;\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n/**\n * Determines whether a field should be ignored during depth calculation.\n *\n * Introspection field handling is controlled by the `introspectionMode` parameter:\n * - `\"all\"` — ignore every `__`-prefixed field\n * - `\"typename\"` (default) — only ignore `__typename`\n * - `\"none\"` — count all introspection fields toward depth\n *\n * **Warning:** When `ignoreMode: \"skip\"` is set, an ignored field's **entire\n * subtree** is skipped — not just the depth increment. Ignoring a composite field\n * bypasses all depth protection for everything nested under it. Use\n * `ignoreMode: \"exclude\"` (default) to skip only the depth increment while still\n * traversing children.\n *\n * @param fieldName - The name of the field to check\n * @param ignore - Array of ignore rules (strings, RegExp, or functions)\n * @param caseInsensitive - Whether to use case-insensitive matching for string rules\n * @param introspectionMode - How to handle introspection fields\n * @returns `true` if the field should be skipped, `false` otherwise\n *\n * @example\n * ```typescript\n * shouldIgnoreField(\"__typename\", []); // true (introspection, default mode)\n * shouldIgnoreField(\"__schema\", [], false, \"typename\"); // false (only __typename ignored)\n * shouldIgnoreField(\"__schema\", [], false, \"all\"); // true (all __ fields ignored)\n * shouldIgnoreField(\"metadata\", [\"metadata\"]); // true (exact match)\n * shouldIgnoreField(\"Metadata\", [\"metadata\"], true); // true (case-insensitive)\n * shouldIgnoreField(\"posts\", [/^internal/]); // false (no match)\n * ```\n */\nexport function shouldIgnoreField(\n\tfieldName: string,\n\tignore?: IgnoreRule[],\n\tcaseInsensitive = false,\n\tintrospectionMode: IntrospectionMode = \"typename\",\n): boolean {\n\tif (introspectionMode === \"all\" && fieldName.startsWith(\"__\")) {\n\t\treturn true;\n\t}\n\n\tif (introspectionMode === \"typename\" && fieldName === \"__typename\") {\n\t\treturn true;\n\t}\n\n\tif (!ignore || ignore.length === 0) {\n\t\treturn false;\n\t}\n\n\t// Precompute lowercased field name once for all string rule comparisons\n\tconst normalizedFieldName = caseInsensitive ? fieldName.toLowerCase() : fieldName;\n\n\tfor (const rule of ignore) {\n\t\tif (typeof rule === \"string\") {\n\t\t\tconst normalizedRule = caseInsensitive ? rule.toLowerCase() : rule;\n\t\t\tif (normalizedRule === normalizedFieldName) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t} else if (rule instanceof RegExp) {\n\t\t\ttry {\n\t\t\t\t// Reset lastIndex for stateful regexes (/g, /y flags) to ensure\n\t\t\t\t// consistent results. This mutates the RegExp object, which is\n\t\t\t\t// intentional. Without the reset, repeated calls with the same\n\t\t\t\t// global or sticky regex produce inconsistent results.\n\t\t\t\tif (rule.global || rule.sticky) {\n\t\t\t\t\trule.lastIndex = 0;\n\t\t\t\t}\n\t\t\t\tif (rule.test(fieldName)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\t// Frozen or exotic RegExp objects throw on lastIndex mutation or\n\t\t\t\t// test(). Wrap as IgnoreRuleError so the caller can handle it\n\t\t\t\t// consistently with function rule errors.\n\t\t\t\tconst message = `Ignore rule RegExp threw for field \"${fieldName}\": ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`;\n\t\t\t\tconst wrapped = new Error(message, { cause: error });\n\t\t\t\twrapped.name = \"IgnoreRuleError\";\n\t\t\t\tthrow wrapped;\n\t\t\t}\n\t\t} else {\n\t\t\ttry {\n\t\t\t\tif (rule(fieldName)) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tconst message = `Ignore rule function threw for field \"${fieldName}\": ${\n\t\t\t\t\terror instanceof Error ? error.message : String(error)\n\t\t\t\t}`;\n\t\t\t\tconst wrapped = new Error(message, { cause: error });\n\t\t\t\twrapped.name = \"IgnoreRuleError\";\n\t\t\t\tthrow wrapped;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn false;\n}\n","import { isUnsafeRegExp } from \"./ignore.js\";\nimport type { DepthCallback, DepthLimitOptions, IgnoreRule } from \"./types.js\";\n\n/** Valid values for the `directiveMode` option. */\nconst DIRECTIVE_MODES = new Set<string>([\"cap\", \"override\"]);\n\n/** Valid values for the `ignoreMode` option. */\nconst IGNORE_MODES = new Set<string>([\"exclude\", \"skip\"]);\n\n/** Valid values for the `ignoreIntrospection` option. */\nconst INTROSPECTION_MODES = new Set<string>([\"all\", \"none\", \"typename\"]);\n\n/**\n * Normalized depthLimit options with validated ignore rules.\n */\nexport type NormalizedDepthLimitOptions = Omit<DepthLimitOptions, \"ignore\"> & {\n\tignore?: IgnoreRule[];\n};\n\n/**\n * Validates that a value is a boolean or undefined.\n */\nfunction assertBooleanOption(name: string, value: unknown): void {\n\tif (value !== undefined && typeof value !== \"boolean\") {\n\t\tthrow new TypeError(`Invalid ${name}: expected boolean, received ${typeof value}.`);\n\t}\n}\n\n/**\n * Determines whether a value is a valid ignore rule.\n */\nfunction isIgnoreRule(rule: unknown): rule is IgnoreRule {\n\treturn typeof rule === \"function\" || rule instanceof RegExp || typeof rule === \"string\";\n}\n\n/**\n * Normalizes and validates ignore rules.\n */\nfunction normalizeIgnoreRules(ignore: DepthLimitOptions[\"ignore\"]): IgnoreRule[] | undefined {\n\tif (ignore == null) {\n\t\treturn undefined;\n\t}\n\n\tconst rules: unknown[] = Array.isArray(ignore) ? ignore : [ignore];\n\n\tfor (const [index, rule] of rules.entries()) {\n\t\tif (!isIgnoreRule(rule)) {\n\t\t\tconst receivedType = Array.isArray(rule) ? \"array\" : rule === null ? \"null\" : typeof rule;\n\t\t\tthrow new TypeError(\n\t\t\t\t`Invalid ignore rule at index ${index}: expected string, RegExp, or function, received ${receivedType}.`,\n\t\t\t);\n\t\t}\n\n\t\tif (rule instanceof RegExp) {\n\t\t\tconst reason = isUnsafeRegExp(rule);\n\t\t\tif (reason) {\n\t\t\t\tthrow new TypeError(\n\t\t\t\t\t`Unsafe RegExp ignore rule at index ${index}: /${rule.source}/${rule.flags} - ${reason}. Use a simpler pattern to avoid catastrophic backtracking.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rules as IgnoreRule[];\n}\n\n/**\n * Normalizes and validates depthLimit options.\n */\nfunction normalizeDepthLimitOptions(options: DepthLimitOptions): NormalizedDepthLimitOptions {\n\tif (\n\t\toptions.maxNodes !== undefined &&\n\t\t(!Number.isSafeInteger(options.maxNodes) || options.maxNodes <= 0)\n\t) {\n\t\tthrow new TypeError(\"Invalid maxNodes: expected a positive safe integer.\");\n\t}\n\tassertBooleanOption(\"caseInsensitiveIgnore\", options.caseInsensitiveIgnore);\n\n\tif (options.directiveMode !== undefined && !DIRECTIVE_MODES.has(options.directiveMode)) {\n\t\tthrow new TypeError(\n\t\t\t`Invalid directiveMode: \"${options.directiveMode}\". Must be \"cap\" or \"override\".`,\n\t\t);\n\t}\n\n\tif (\n\t\toptions.ignoreIntrospection !== undefined &&\n\t\t!INTROSPECTION_MODES.has(options.ignoreIntrospection)\n\t) {\n\t\tthrow new TypeError(\n\t\t\t`Invalid ignoreIntrospection: \"${options.ignoreIntrospection}\". Must be \"all\", \"none\", or \"typename\".`,\n\t\t);\n\t}\n\n\tif (options.ignoreMode !== undefined && !IGNORE_MODES.has(options.ignoreMode)) {\n\t\tthrow new TypeError(\n\t\t\t`Invalid ignoreMode: \"${options.ignoreMode}\". Must be \"exclude\" or \"skip\".`,\n\t\t);\n\t}\n\n\tassertBooleanOption(\"limitIgnoredRecursion\", options.limitIgnoredRecursion);\n\tassertBooleanOption(\"shortCircuit\", options.shortCircuit);\n\tassertBooleanOption(\"useDirective\", options.useDirective);\n\n\tconst ignore = normalizeIgnoreRules(options.ignore);\n\treturn { ...options, ignore };\n}\n\n/**\n * Normalizes the optional depthLimit arguments.\n */\nexport function normalizeDepthLimitArgs(\n\toptions: DepthLimitOptions | DepthCallback | undefined,\n\tcallback: DepthCallback | undefined,\n): { callback?: DepthCallback; options?: NormalizedDepthLimitOptions } {\n\tif (callback !== undefined && typeof callback !== \"function\") {\n\t\tthrow new TypeError(\"Invalid callback: expected a function.\");\n\t}\n\n\tif (typeof options === \"function\") {\n\t\tif (callback) {\n\t\t\tthrow new TypeError(\"Invalid depthLimit arguments: callback provided twice.\");\n\t\t}\n\n\t\treturn { callback: options, options: undefined };\n\t}\n\n\tif (\n\t\toptions !== undefined &&\n\t\t(options === null || typeof options !== \"object\" || Array.isArray(options))\n\t) {\n\t\tconst receivedType = Array.isArray(options)\n\t\t\t? \"array\"\n\t\t\t: options === null\n\t\t\t\t? \"null\"\n\t\t\t\t: typeof options;\n\t\tthrow new TypeError(`Invalid options: expected an object, received ${receivedType}.`);\n\t}\n\n\treturn {\n\t\tcallback,\n\t\toptions: options ? normalizeDepthLimitOptions(options) : undefined,\n\t};\n}\n\n/**\n * Creates a null-prototype record for internal depth result accumulation.\n */\nexport function createDepthResultRecord(): Record<string, number> {\n\treturn Object.create(null) as Record<string, number>;\n}\n\n/**\n * Safely assigns a depth entry without allowing prototype pollution.\n */\nexport function setDepthResult(target: Record<string, number>, key: string, value: number): void {\n\tObject.defineProperty(target, key, {\n\t\tconfigurable: true,\n\t\tenumerable: true,\n\t\tvalue,\n\t\twritable: true,\n\t});\n}\n","// Only names are needed, keeping this helper compatible with GraphQL 16/17 ASTs.\ninterface NamedOperation {\n\treadonly name?: { readonly value: string };\n}\n\n/**\n * Creates a stable allocator for callback operation names.\n *\n * Ensures:\n * - Anonymous names never collide with explicit operation names\n * - Duplicate named operations receive deterministic suffixes\n * - Generated names do not overwrite previous callback entries\n */\nexport function createOperationNameAllocator(\n\toperations: readonly NamedOperation[],\n): (operation: NamedOperation) => string {\n\tconst explicitNames = new Set<string>();\n\tfor (const operation of operations) {\n\t\tif (operation.name?.value) {\n\t\t\texplicitNames.add(operation.name.value);\n\t\t}\n\t}\n\n\tconst usedNames = new Set<string>();\n\tconst namedCounts = new Map<string, number>();\n\tlet anonymousCount = 0;\n\n\treturn (operation: NamedOperation): string => {\n\t\tconst explicitName = operation.name?.value;\n\t\tif (explicitName) {\n\t\t\tlet suffix = namedCounts.get(explicitName) ?? 0;\n\t\t\tlet candidate = suffix === 0 ? explicitName : `${explicitName}_${suffix}`;\n\n\t\t\twhile (usedNames.has(candidate) || (suffix > 0 && explicitNames.has(candidate))) {\n\t\t\t\tsuffix++;\n\t\t\t\tcandidate = `${explicitName}_${suffix}`;\n\t\t\t}\n\n\t\t\tnamedCounts.set(explicitName, suffix + 1);\n\t\t\tusedNames.add(candidate);\n\t\t\treturn candidate;\n\t\t}\n\n\t\tanonymousCount++;\n\t\tlet candidate = anonymousCount === 1 ? \"[anonymous]\" : `[anonymous:${anonymousCount}]`;\n\t\twhile (usedNames.has(candidate) || explicitNames.has(candidate)) {\n\t\t\tanonymousCount++;\n\t\t\tcandidate = `[anonymous:${anonymousCount}]`;\n\t\t}\n\n\t\tusedNames.add(candidate);\n\t\treturn candidate;\n\t};\n}\n"],"mappings":"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","names":["import_graphql","import_graphql","parentType","candidate"]}