import type { Workspace } from '../../../pm/index.ts';
import type { CheckPackageParams } from './checkPackageTypes.ts';
export interface PeerSource {
    /** Dependency chain for transitive peers, e.g. ['direct-dep', 'transitive-dep'] */
    chain?: string[];
    isRuntimeDep: boolean;
    requiredBy: string;
}
/**
 * Peer-chain forwarding policy (`commands.apiExposure.peerForwarding`),
 * honored by deplint in `classifier: 'aei'` mode. Under `'when-used'` and
 * `'when-exposed'`, a peer contract imposed by a dependency chain only
 * forwards into this package's `peerDependencies` when the peer appears in
 * `importedModules`; otherwise `devDependencies` satisfy it locally and
 * installers resolve the consumer-side contract. The caller builds
 * `importedModules` to match the mode: every import for `'when-used'`,
 * only runtime dist imports plus shipped-d.ts type imports (the
 * enforcement-grade exposure signal) for `'when-exposed'`.
 */
export interface PeerForwardingPolicy {
    importedModules: ReadonlySet<string>;
    mode: 'always' | 'when-exposed' | 'when-used';
}
/** True when the policy (if any) obliges this package to forward `peer`. */
export declare function isPeerForwarded(policy: PeerForwardingPolicy | undefined, peer: string): boolean;
export interface UnsatisfiedPeer {
    hasRuntimeSource: boolean;
    /** True when runtime chains require the peer but the forwarding policy
     * ruled it inherited-only (never imported here); satisfied by devDeps. */
    inherited?: boolean;
    installedVersion?: string;
    /** Sources (requiring deps) whose declared peer range the installed version
     * does not satisfy. Populated only for `reason: 'version-mismatch'`. */
    mismatchedSources?: PeerSource[];
    peer: string;
    reason: 'missing' | 'version-mismatch' | 'under-exposed';
    sources: PeerSource[];
    versionRange: string;
}
/**
 * Returns true when every requiring source declares this peer as optional in
 * its own `peerDependenciesMeta`. Empty sources is vacuously true; callers
 * that promote without a known source set should not rely on this signal.
 */
export declare function isPeerOptionalInAll(location: string, peer: string, sources: PeerSource[]): boolean;
/**
 * Returns the full set of peer dependency names required by all deps and devDeps.
 * Used to prevent the unused-dependency checks from removing deps that satisfy
 * transitive peer requirements.
 */
export declare function getRequiredTransitivePeers(location: string, { dependencies, devDependencies, peerDependencies, }: CheckPackageParams): Set<string>;
/**
 * Like `getRequiredTransitivePeers` but excludes peers that every requiring
 * source marks optional. Use this when deciding whether a devDependency is
 * "unused" — an all-optional transitive peer is not actually needed, so it
 * should be eligible for removal if it isn't directly imported.
 */
export declare function getRequiredNonOptionalTransitivePeers(location: string, { dependencies, devDependencies, peerDependencies, }: CheckPackageParams): Set<string>;
export interface TransitivePeerSourceOptions {
    /**
     * Drop sources whose peer contract is already discharged inside the
     * dependency tree itself. Package managers resolve a peer against the
     * declaring package's parent context, so the contract never reaches this
     * package's consumers when an ancestor in the chain either IS the peer
     * (self-rooted, e.g. `browserslist > update-browserslist-db` peering back
     * on browserslist) or provides the peer from its own `dependencies`
     * (e.g. `espree` shipping `acorn` for `acorn-jsx`).
     */
    excludeSatisfiedInChain?: boolean;
}
/**
 * Like `getRequiredNonOptionalTransitivePeers` but only counts peers reachable
 * through at least one **runtime** (non-dev) dependency chain, and returns the
 * requiring sources for each peer. Use this when the caller needs to explain
 * *which* dependency imposes the peer contract (e.g. AEI evidence lines).
 */
export declare function getRuntimeRootedNonOptionalTransitivePeerSources(location: string, { dependencies, devDependencies, peerDependencies, }: CheckPackageParams, options?: TransitivePeerSourceOptions): Map<string, PeerSource[]>;
/**
 * Like `getRequiredNonOptionalTransitivePeers` but only counts peers reachable
 * through at least one **runtime** (non-dev) dependency chain. Use this for
 * `peerDependencies` retention: a peer reached only via devDep chains has no
 * runtime contract to forward to consumers, so it should not be kept in
 * `peerDependencies` even if some devDep happens to require it.
 */
export declare function getRuntimeRootedNonOptionalTransitivePeers(location: string, params: CheckPackageParams): Set<string>;
export declare function findUnsatisfiedPeers({ name, location }: Workspace, { dependencies, devDependencies, peerDependencies, peerDependencyVersions, }: CheckPackageParams, exclude?: Set<string>, isTerminal?: boolean, forcePeerOptional?: Map<string, boolean>, forceDevs?: Set<string>, forwarding?: PeerForwardingPolicy): UnsatisfiedPeer[];
/**
 * For terminal packages (apps): runtime peers → dependencies, dev-only → devDependencies.
 * For library packages: runtime peers → peerDependencies + devDependencies (peer passes
 * the requirement to consumers, devDep satisfies it for the library's own development).
 * Dev-only peers → devDependencies only.
 */
export declare function resolvePeerTargetSections(hasRuntimeSource: boolean, isTerminal: boolean): string[];
//# sourceMappingURL=getUnsatisfiedPeerDependencies.d.ts.map