import type { Rule } from 'eslint';
import type estree from 'estree';
import type { ParserServicesWithTypeInformation } from '@typescript-eslint/utils';
import ts from 'typescript';
import * as Angular from './angular.js';
import * as AwsCdk from './assertions-aws-cdk.js';
import * as Chai from './chai.js';
import { isGlobalTSExpectAssertion, isNodeAssertAssertion, isNodeAssertTSAssertion } from './assertion-detection.js';
import * as NodeTest from './node-test.js';
import * as Sinon from './sinon.js';
import * as Supertest from './supertest.js';
import * as Uvu from './uvu.js';
import * as Vitest from './vitest.js';
/**
 * Every assertion framework the analyzer can recognise, keyed by a stable profile name.
 *
 * This is the single catalog: a framework is added once here — its module specifiers and its AST
 * and type-aware detectors — and rules opt in by listing its key in a profile. Nothing here decides
 * what a match *means*; that is the rule's job, expressed as the profile's extension value (see
 * {@link AssertionExecution} for S8784's script-capable / runner-bound split). A rule that never
 * lists a key is blind to that framework, both for `imports`/`dependencies` gating and detection.
 *
 * `imports` are module specifiers whose presence in the linted file proves the framework is in
 * play; `dependencies` are packages that expose their assertion API as globals, so a manifest
 * dependency is enough and no import appears in the file.
 */
declare const assertionFrameworks: {
    angular: {
        imports: string[];
        dependencies: never[];
        isAssertion: () => false;
        isTSAssertion: typeof Angular.isTSAssertion;
    };
    chai: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof Chai.isAssertion;
        isTSAssertion: (services: ParserServicesWithTypeInformation, node: ts.Node) => boolean;
    };
    sinon: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof Sinon.isAssertion;
        isTSAssertion: typeof Sinon.isTSAssertion;
    };
    supertest: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof Supertest.isAssertion;
        isTSAssertion: typeof Supertest.isTSAssertion;
    };
    nodeAssert: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof isNodeAssertAssertion;
        isTSAssertion: typeof isNodeAssertTSAssertion;
    };
    nodeTest: {
        imports: never[];
        dependencies: never[];
        isAssertion: typeof NodeTest.isAssertion;
        isTSAssertion: typeof NodeTest.isTSAssertion;
    };
    uvu: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof Uvu.isAssertion;
        isTSAssertion: typeof Uvu.isTSAssertion;
    };
    vitest: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof Vitest.isAssertion;
        isTSAssertion: typeof Vitest.isTSAssertion;
    };
    cypress: {
        imports: never[];
        dependencies: string[];
        isAssertion: (_context: Rule.RuleContext, node: estree.Node) => boolean;
        isTSAssertion: (_services: ParserServicesWithTypeInformation, node: ts.Node) => boolean;
    };
    globalExpect: {
        imports: string[];
        dependencies: string[];
        isAssertion: (context: Rule.RuleContext, node: estree.Node) => boolean;
        isTSAssertion: typeof isGlobalTSExpectAssertion;
    };
    awsCdk: {
        imports: string[];
        dependencies: never[];
        isAssertion: typeof AwsCdk.isAssertion;
        isTSAssertion: typeof AwsCdk.isTSAssertion;
    };
};
type AssertionFrameworkKey = keyof typeof assertionFrameworks;
/**
 * A rule's selection of frameworks from {@link assertionFrameworks}, each mapped to whatever that
 * rule needs to know about it (`T`). Rules declare one as a module constant, so the set of
 * frameworks a rule reacts to is readable in one place instead of being implied by which helper it
 * happens to call.
 *
 * Rules use the two concrete aliases below, never this generic directly: `T` is what makes an
 * evidence profile and an execution profile different types, and picking `T` per call site is how
 * they would drift back into being interchangeable.
 */
type AssertionFrameworkProfile<T> = Partial<Record<AssertionFrameworkKey, T>>;
/**
 * A profile covering every framework in {@link assertionFrameworks}, for rules that react to all of
 * them. Derived from the catalog rather than written out at the call site, so a framework added to
 * the catalog reaches those rules instead of being silently invisible to them — an opt-in catalog
 * makes an omission a false negative with nothing to fail.
 *
 * `overrides` carries the extension for the frameworks that need one; every other key gets `{}`.
 * Call it once per rule, at module scope: {@link getFrameworkEntries} caches on profile identity,
 * so a fresh object per `create()` would rebuild the entries for every linted file.
 */
export declare function allAssertionFrameworks(overrides?: AssertionEvidenceProfile): AssertionEvidenceProfile;
/**
 * Extra per-framework detection a rule can bolt onto the catalog's own detectors.
 *
 * `isTSAssertionFallback` runs when the catalog's type-aware detector misses. It is
 * library-agnostic by design: the type-aware resolver only follows declaration initializers, so
 * any framework whose assertion object is *assigned* in test setup rather than declared with an
 * initializer needs it. AWS CDK is simply the only one that does today.
 */
type AssertionEvidenceExtension = {
    isTSAssertionFallback?: (context: Rule.RuleContext, services: ParserServicesWithTypeInformation, node: ts.Node) => boolean;
};
/**
 * Whether a framework's assertions can run without a test runner. Script-capable ones are ordinary
 * libraries usable in a plain `node file.js`; runner-bound ones only exist because a runner
 * executes the file. Used as a profile extension by rules that treat the two differently.
 */
export type AssertionExecution = 'script-capable' | 'runner-bound';
/**
 * Profile for rules that only ask whether an assertion is present. `{}` selects a framework with no
 * extra behaviour; see {@link AssertionEvidenceExtension} for what an entry may carry.
 */
export type AssertionEvidenceProfile = AssertionFrameworkProfile<AssertionEvidenceExtension>;
/**
 * Profile for rules that additionally reason about {@link AssertionExecution}.
 *
 * Deliberately not interchangeable with {@link AssertionEvidenceProfile}: an execution profile
 * carries strings, which do not satisfy the evidence extension's object shape, so passing one to an
 * evidence entry point is a compile error rather than a silently ignored extension.
 *
 * Like evidence profiles, this is opt-in: a rule only classifies frameworks whose assertion
 * detectors it can use.
 */
export type AssertionExecutionProfile = AssertionFrameworkProfile<AssertionExecution>;
/**
 * Whether the linted file imports, or the project depends on, any framework in `profile`. Rules
 * gate on this to stay silent in files that are not tests, before doing any per-node work.
 */
export declare function hasAssertionEvidenceSource(context: Rule.RuleContext, profile: AssertionEvidenceProfile): boolean;
/**
 * Whether `node` is an assertion call from any framework in `profile`. Pure-AST: needs no type
 * information. Frameworks outside the profile are invisible, so this answers "did the rule see an
 * assertion it cares about?", not "is this an assertion?".
 */
export declare function isAssertionEvidence(context: Rule.RuleContext, node: estree.Node, profile: AssertionEvidenceProfile): boolean;
/**
 * Type-checker-aware counterpart of {@link isAssertionEvidence}, operating on TypeScript AST nodes.
 * Used when parser services are available to follow resolved types across declarations, and falls
 * back to each profile entry's {@link AssertionEvidenceExtension.isTSAssertionFallback} when the
 * catalog's own type-aware detector misses.
 */
export declare function isTypeScriptAssertionEvidence(context: Rule.RuleContext, services: ParserServicesWithTypeInformation, node: ts.Node, profile: AssertionEvidenceProfile): boolean;
/**
 * {@link hasAssertionEvidenceSource} for profiles carrying an {@link AssertionExecution}. Same
 * check — the separate name keeps a rule's gating call and its per-node call reading against the
 * same vocabulary.
 */
export declare function hasAssertionExecutionSource(context: Rule.RuleContext, profile: AssertionExecutionProfile): boolean;
/**
 * The `extension` of the first profile framework that claims `node`, or `undefined` if none does.
 *
 * Classification is per *node*, not per statement, and a single assertion statement often has
 * several matching nodes that do not agree. A chai `expect(x).to.equal(y)` matches the Chai
 * detector on the inner `chai.expect(...)` call and the name-based global-`expect` detector on
 * the outer `.to.equal(...)` call, so with an {@link AssertionExecution} profile the same
 * statement yields both `script-capable` and `runner-bound`. Callers that reason about the
 * classification must combine the nodes of a statement themselves — see how S8784 ORs
 * `script-capable` across a statement rather than trusting any single node.
 */
export declare function getAssertionExecution(context: Rule.RuleContext, node: estree.Node, profile: AssertionExecutionProfile): AssertionExecution | undefined;
export {};
