import type { AbsolutePath, RelativePath } from '@-xun/fs';
import type { GenericProjectMetadata, RootPackage, WorkspacePackage, WorkspacePackageName, XPackageJson } from '@-xun/project-types';
import type { JsonObject, LiteralUnion } from 'type-fest';
/**
 * A type representing the name of an available dummy repository.
 */
export type RepositoryName = 'badHybridrepoBadSpecifiers' | 'badHybridrepoTopologicalCycle' | 'badHybridrepoTopologicalPrivate' | 'badMonorepo' | 'badMonorepoDuplicateIdUnnamed' | 'badMonorepoDuplicateName' | 'badMonorepoDuplicateIdNamed' | 'badMonorepoEmptyMdFiles' | 'badMonorepoNextjsProject' | 'badMonorepoNonPackageDir' | 'badMonorepoTopologicalCycle' | 'badMonorepoTopologicalPrivate' | 'badPolyrepo' | 'badPolyrepoBadType' | 'badPolyrepoConflictingAttributes' | 'badPolyrepoEmptyMdFiles' | 'badPolyrepoEmptyPackageJson' | 'badPolyrepoImporter' | 'badPolyrepoNextjsProject' | 'badPolyrepoNonPackageDir' | 'badPolyrepoTsbuildinfo' | 'goodHybridrepo' | 'goodHybridrepoComplexIgnore' | 'goodHybridrepoNotPrivate' | 'goodHybridrepoMultiversal' | 'goodHybridrepoSelfRef' | 'goodHybridrepoTopological' | 'goodHybridrepoTopologicalPrivate' | 'goodHybridrepoTopologicalSelfRef' | 'goodMonorepo' | 'goodMonorepoSimilarIds' | 'goodMonorepoNegatedPaths' | 'goodMonorepoNextjsProject' | 'goodMonorepoSimplePaths' | 'goodMonorepoWeirdAbsolute' | 'goodMonorepoWeirdBoneless' | 'goodMonorepoWeirdOverlap' | 'goodMonorepoWeirdSameNames' | 'goodMonorepoWeirdYarn' | 'goodMonorepoWindows' | 'goodMonorepoNoSrc' | 'goodMonorepoTopological' | 'goodMonorepoTopologicalPrivate' | 'goodMonorepoTopologicalSelfRef' | 'goodPolyrepo' | 'goodPolyrepoNextjsProject' | 'goodPolyrepoNoEnv' | 'goodPolyrepoNoSrcYesDefaultEnv' | 'goodPolyrepoOnlyDefaultEnv' | 'goodPolyrepoTopologicalPrivate' | 'goodPolyrepoTopologicalSelfRef' | 'repoThatDoesNotExist';
/**
 * A type representing a dummy monorepo or polyrepo project's metadata.
 */
export type Repository = {
  root: AbsolutePath;
  json: XPackageJson;
  attributes: RootPackage['attributes'];
  namedPackageMapData: PackageMapEntry[];
  unnamedPackageMapData: PackageMapEntry[];
  brokenPackageRoots: AbsolutePath[];
};
/**
 * A type represents an object that will be expanded into a
 * {@link PackageMapEntry}.
 */
export type PackageMapDatum = {
  /**
   * A package's name (for named packages) or its id (for unnamed packages).
   */
  name: string;
  /**
   * A **relative** path to a dummy project root (will be made absolute later).
   */
  root: RelativePath | string;
  attributes: WorkspacePackage['attributes'];
};
/**
 * A type represents a single entry of a packages map.
 *
 * `name` represents a package's name (for named packages) or its id (for
 * unnamed packages).
 */
export type PackageMapEntry = [name: string, workspacePackage: WorkspacePackage];
/**
 * Return a {@link ProjectMetadata} instance from an existing dummy repository.
 */
export declare function dummyToProjectMetadata(repositoryName: RepositoryName, cwdPackageName?: LiteralUnion<'self', WorkspacePackageName>): GenericProjectMetadata;
/**
 * Apply one or more patches to the per-`filePath` ({@link AbsolutePath}) JSON
 * file content returned by the sync and async forms of
 * {@link fs.readXPackageJsonAtRoot}, {@link fs.readJson}, and
 * {@link fs.readJsonc}.
 *
 * Note that (1) successive calls to this function overwrite previous calls and
 * (2) patches are not cached. The real JSON read results _are_ cached
 * (depending on `useCached`); however, these results are not directly visible
 * to the caller as the patch is re-applied on every invocation, **meaning a new
 * object is always returned**.
 *
 * Also note that this function only works with files containing a _root JSON
 * object_. Attempting to use this function with files containing some other
 * JSON type at its root, like an array or primitive, will result in undefined
 * behavior.
 *
 * @returns `spec`
 */
export declare function patchJsonObjectReaders(
/**
 * The JSON patches to apply per `filePath` {@link AbsolutePath}. When
 * `filePath` is equal to `"*"`, it will be used to patch all JSON
 * imports but can be overwritten by a more specific `filePath` in the same
 * `spec`.
 */
spec: { [filePath in AbsolutePath | '*']?: JsonObject },
/**
 * Options that influence the patching process.
 */
options?: {
  /**
   * Whether to add _missing_ keys from the patch to the result but not
   * overwrite any existing keys (`false`), _completely_ replace the entire
   * result with the patch (`true`), or `Object.assign` the patch on top of
   * the result (`undefined`).
   *
   * Note that valid {@link XPackageJson} objects must always have a `name`
   * property defined.
   *
   * @default undefined
   */
  replace?: boolean;
}): Record<string, JsonObject | undefined>;
/**
 * A collection of repositories representing dummy monorepo and polyrepo
 * projects. Useful for testing purposes.
 */
export declare const repositories: Record<RepositoryName, Repository>;