import { type AstNode } from './util'; /** * Options for the require-api-details-for-crud-function rule. */ export interface FirebaseRequireApiDetailsForCrudFunctionRuleOptions { /** * Verb fragments that pair with the `ModelFunction` suffix to identify a CRUD function * type annotation. Defaults to {@link DEFAULT_CRUD_FUNCTION_TYPE_VERBS}. */ readonly typeVerbs?: readonly string[]; /** * Factory function name expected on the initializer. Defaults to {@link DEFAULT_API_DETAILS_FACTORY_NAME}. */ readonly factoryName?: string; /** * Declarator names to exempt from the rule. Mainly an escape hatch for tests. */ readonly ignoreNames?: readonly string[]; } /** * ESLint rule definition for require-api-details-for-crud-function. */ export interface FirebaseRequireApiDetailsForCrudFunctionRuleDefinition { readonly meta: { readonly type: 'problem'; readonly fixable: 'code'; readonly docs: { readonly description: string; readonly recommended: boolean; }; readonly messages: Readonly>; readonly schema: readonly object[]; }; create(context: { options: FirebaseRequireApiDetailsForCrudFunctionRuleOptions[]; sourceCode: AstNode; report: (descriptor: { node: AstNode; messageId: string; data?: Record; fix?: (fixer: AstNode) => AstNode | AstNode[]; }) => void; }): Record void>; } /** * ESLint rule that requires every CRUD function declaration — a variable typed as * `On(?:Call)?ModelFunction` (or any app-side alias ending with the same `ModelFunction` * suffix) — to be initialized with a call to `withApiDetails(...)`. * * Handlers that skip the wrapper compile fine but do not attach the `_apiDetails` metadata * (`inputType`, `mcp.visibility`, `analytics`) that downstream tooling — especially the MCP * manifest builder in `packages/firebase-server-mcp` — reads. The handler then silently fails * to appear in the generated MCP server even though the runtime wires it up. * * The rule is purely syntactic: it inspects the declarator's TS type annotation and the * initializer's `CallExpression` callee name. Type assertions (`as`, ``) on the initializer * are unwrapped before the check. * * Auto-fix: wraps the existing initializer as `withApiDetails({ fn: })` (`inputType` * is optional on the config, so the minimal wrap compiles) and — when the default factory is used * and not already in scope — inserts `import { withApiDetails } from '@dereekb/firebase-server';`. * The developer is still expected to add `inputType`; the companion `require-input-type-for-api-details` * rule flags that follow-up where it matters. * * @example * ```ts * // OK — wrapped, surfaces to MCP * export const fooCreate: FooCreateModelFunction = withApiDetails({ * inputType, fn: async (req) => ({}) * }); * * // WARN — missingApiDetails, never reaches MCP (auto-fix wraps it) * export const fooDelete: FooDeleteModelFunction = async (req) => {}; * ``` */ export declare const FIREBASE_REQUIRE_API_DETAILS_FOR_CRUD_FUNCTION_RULE: FirebaseRequireApiDetailsForCrudFunctionRuleDefinition;