import { Package } from '@manypkg/get-packages';
import { JsonValue } from '@backstage/types';

/**
 * Utilities for working with git.
 *
 * @public
 */
declare class GitUtils {
    /**
     * Returns a sorted list of all files that have changed since the merge base
     * of the provided `ref` and HEAD, as well as all files that are not tracked by git.
     */
    static listChangedFiles(ref: string): Promise<string[]>;
    /**
     * Returns the contents of a file at a specific ref.
     */
    static readFileAtRef(path: string, ref: string): Promise<string>;
}

/**
 * Returns try if the current project is a monorepo.
 *
 * @public
 */
declare function isMonoRepo(): Promise<boolean>;

/**
 * Backstage package role, see {@link https://backstage.io/docs/tooling/cli/build-system#package-roles | docs}.
 *
 * @public
 */
type PackageRole = 'frontend' | 'backend' | 'cli' | 'web-library' | 'node-library' | 'common-library' | 'frontend-plugin' | 'frontend-plugin-module' | 'backend-plugin' | 'backend-plugin-module';
/**
 * A type of platform that a package can be built for.
 *
 * @public
 */
type PackagePlatform = 'node' | 'web' | 'common';
/**
 * The type of output that a package can produce.
 *
 * @public
 */
type PackageOutputType = 'bundle' | 'types' | 'esm' | 'cjs';
/**
 * Information about a package role.
 *
 * @public
 */
interface PackageRoleInfo {
    role: PackageRole;
    platform: PackagePlatform;
    output: PackageOutputType[];
}

/**
 * Utilities for working with Backstage package roles.
 *
 * @public
 */
declare class PackageRoles {
    /**
     * Get the associated info for a package role.
     */
    static getRoleInfo(role: string): PackageRoleInfo;
    /**
     * Given package JSON data, get the package role.
     */
    static getRoleFromPackage(pkgJson: unknown): PackageRole | undefined;
    /**
     * Attempt to detect the role of a package from its package.json.
     */
    static detectRoleFromPackage(pkgJson: unknown): PackageRole | undefined;
}

/**
 * A list of the feature types we want to extract from the project
 * and include in the metadata
 *
 * @public
 */
declare const packageFeatureType: readonly ["@backstage/BackendFeature", "@backstage/BackstagePlugin", "@backstage/FrontendPlugin", "@backstage/FrontendModule"];
/**
 * @public
 */
type BackstagePackageFeatureType = (typeof packageFeatureType)[number];
/**
 * Known fields in Backstage package.json files.
 *
 * @public
 */
interface BackstagePackageJson {
    name: string;
    version: string;
    private?: boolean;
    main?: string;
    module?: string;
    types?: string;
    scripts?: {
        [key: string]: string;
    };
    bundled?: boolean;
    type?: 'module' | 'commonjs';
    backstage?: {
        role?: PackageRole;
        moved?: string;
        /**
         * If set to `true`, the package will be treated as an internal package
         * where any imports will be inlined into the consuming package.
         *
         * When set to `true`, the top-level `private` field must be set to `true`
         * as well.
         */
        inline?: boolean;
        /**
         * The ID of the plugin if this is a plugin package. Must always be set for plugin and module packages, and may be set for library packages. A `null` value means that the package is explicitly not a plugin package.
         */
        pluginId?: string | null;
        /**
         * The parent plugin package of a module. Must always and only be set for module packages.
         */
        pluginPackage?: string;
        /**
         * All packages that are part of the plugin. Must always and only be set for plugin packages and plugin library packages.
         */
        pluginPackages?: string[];
        /**
         * The feature types exported from the package, indexed by path.
         */
        features?: Record<string, BackstagePackageFeatureType>;
    };
    exports?: JsonValue;
    typesVersions?: Record<string, Record<string, string[]>>;
    files?: string[];
    publishConfig?: {
        access?: 'public' | 'restricted';
        directory?: string;
        registry?: string;
    };
    repository?: string | {
        type: string;
        url: string;
        directory: string;
    };
    dependencies?: {
        [key: string]: string;
    };
    peerDependencies?: {
        [key: string]: string;
    };
    devDependencies?: {
        [key: string]: string;
    };
    optionalDependencies?: {
        [key: string]: string;
    };
}
/**
 * A local Backstage monorepo package
 *
 * @public
 */
type BackstagePackage = {
    dir: string;
    packageJson: BackstagePackageJson;
};
/**
 * A local package in the monorepo package graph.
 *
 * @public
 */
type PackageGraphNode = {
    /** The name of the package */
    name: string;
    /** The directory of the package */
    dir: string;
    /** The package data of the package itself */
    packageJson: BackstagePackageJson;
    /** All direct local dependencies of the package */
    allLocalDependencies: Map<string, PackageGraphNode>;
    /** All direct local dependencies that will be present in the published package */
    publishedLocalDependencies: Map<string, PackageGraphNode>;
    /** Local dependencies */
    localDependencies: Map<string, PackageGraphNode>;
    /** Local devDependencies */
    localDevDependencies: Map<string, PackageGraphNode>;
    /** Local optionalDependencies */
    localOptionalDependencies: Map<string, PackageGraphNode>;
    /** All direct incoming local dependencies of the package */
    allLocalDependents: Map<string, PackageGraphNode>;
    /** All direct incoming local dependencies that will be present in the published package */
    publishedLocalDependents: Map<string, PackageGraphNode>;
    /** Incoming local dependencies */
    localDependents: Map<string, PackageGraphNode>;
    /** Incoming local devDependencies */
    localDevDependents: Map<string, PackageGraphNode>;
    /** Incoming local optionalDependencies */
    localOptionalDependents: Map<string, PackageGraphNode>;
};
/**
 * Represents a local Backstage monorepo package graph.
 *
 * @public
 */
declare class PackageGraph extends Map<string, PackageGraphNode> {
    /**
     * Lists all local packages in a monorepo.
     */
    static listTargetPackages(): Promise<BackstagePackage[]>;
    /**
     * Creates a package graph from a list of local packages.
     */
    static fromPackages(packages: Package[]): PackageGraph;
    /**
     * Traverses the package graph and collects a set of package names.
     *
     * The traversal starts at the provided list names, and continues
     * throughout all the names returned by the `collectFn`, which is
     * called once for each seen package.
     */
    collectPackageNames(startingPackageNames: string[], collectFn: (pkg: PackageGraphNode) => Iterable<string> | undefined): Set<string>;
    /**
     * Lists all packages that have changed since a given git ref.
     *
     * @remarks
     *
     * If the `analyzeLockfile` option is set to true, the change detection will
     * also consider changes to the dependency management lockfile.
     */
    listChangedPackages(options: {
        ref: string;
        analyzeLockfile?: boolean;
    }): Promise<PackageGraphNode[]>;
}

/**
 * An entry for a single difference between two {@link Lockfile}s.
 *
 * @public
 */
type LockfileDiffEntry = {
    name: string;
    range: string;
};
/**
 * Represents the difference between two {@link Lockfile}s.
 *
 * @public
 */
type LockfileDiff = {
    added: LockfileDiffEntry[];
    changed: LockfileDiffEntry[];
    removed: LockfileDiffEntry[];
};
/**
 * Represents a package manager lockfile.
 *
 * @public
 */
declare class Lockfile {
    private readonly packages;
    private readonly data;
    /**
     * Load a {@link Lockfile} from a file path.
     */
    static load(path: string): Promise<Lockfile>;
    /**
     * Parse lockfile contents into a {@link Lockfile}.
     *
     * @public
     */
    static parse(content: string): Lockfile;
    private constructor();
    /**
     * Creates a simplified dependency graph from the lockfile data, where each
     * key is a package, and the value is a set of all packages that it depends on
     * across all versions.
     */
    createSimplifiedDependencyGraph(): Map<string, Set<string>>;
    /**
     * Diff with another lockfile, returning entries that have been
     * added, changed, and removed compared to the other lockfile.
     */
    diff(otherLockfile: Lockfile): LockfileDiff;
    /**
     * Generates a sha1 hex hash of the dependency graph for a package.
     */
    getDependencyTreeHash(startName: string): string;
}

export { type BackstagePackage, type BackstagePackageFeatureType, type BackstagePackageJson, GitUtils, Lockfile, type LockfileDiff, type LockfileDiffEntry, PackageGraph, type PackageGraphNode, type PackageOutputType, type PackagePlatform, type PackageRole, type PackageRoleInfo, PackageRoles, isMonoRepo, packageFeatureType };
