/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 *
 * @format
 * @oncall react_native
 */

import type { TransformResultDependency } from "../metro/DeltaBundler/types";
export type Result<TResolution, TCandidates> = {
  readonly type: "resolved";
  readonly resolution: TResolution;
} | {
  readonly type: "failed";
  readonly candidates: TCandidates;
};
export type Resolution = FileResolution | {
  readonly type: "empty";
};
export interface SourceFileResolution {
  readonly type: "sourceFile";
  readonly filePath: string;
}
export type AssetFileResolution = ReadonlyArray<string>;
export interface AssetResolution {
  readonly type: "assetFiles";
  readonly filePaths: AssetFileResolution;
}
export type FileResolution = AssetResolution | SourceFileResolution;
export interface FileAndDirCandidates {
  readonly dir?: null | FileCandidates;
  readonly file?: null | FileCandidates;
}
/**
 * This is a way to describe what files we tried to look for when resolving
 * a module name as file. This is mainly used for error reporting, so that
 * we can explain why we cannot resolve a module.
 */
export type FileCandidates = {
  readonly type: "asset";
  readonly name: string;
} | {
  readonly type: "sourceFile";
  filePathPrefix: string;
  readonly candidateExts: ReadonlyArray<string>;
};
export interface ExportsLikeMap {
  readonly [subpathOrCondition: string]: string | ExportsLikeMap | null;
}
/** "exports" mapping where values may be legacy Node.js <13.7 array format. */
export interface ExportMapWithFallbacks {
  readonly [subpath: string]: ExportsLikeMap[keyof ExportsLikeMap] | ExportValueWithFallback;
}
/** "exports" subpath value when in legacy Node.js <13.7 array format. */
export type ExportValueWithFallback = ReadonlyArray<ExportsLikeMap | string> | ReadonlyArray<ReadonlyArray<unknown>>;
export type ExportsField = string | ReadonlyArray<string> | ExportValueWithFallback | ExportsLikeMap | ExportMapWithFallbacks;
export type FlattenedExportMap = ReadonlyMap<string, string | null>;
export type NormalizedExportsLikeMap = Map<string, null | string | ExportsLikeMap>;
export interface PackageJson {
  readonly name?: string;
  readonly main?: string;
  readonly exports?: ExportsField;
  readonly imports?: ExportsLikeMap;
}
export interface PackageInfo {
  readonly packageJson: PackageJson;
  readonly rootPath: string;
}
export interface PackageForModule extends PackageInfo {
  readonly packageRelativePath: string;
}
/**
 * Check existence of a single file.
 */
export type DoesFileExist = (filePath: string) => boolean;
/**
 * Performs a lookup against an absolute or project-relative path to determine
 * whether it exists as a file or directory. Follows any symlinks, and returns
 * a real absolute path on existence.
 */
export type FileSystemLookup = (absoluteOrProjectRelativePath: string) => {
  exists: false;
} | {
  exists: true;
  type?: "f" | "d";
  realPath: string;
};
/**
 * Given a directory path and the base asset name, return a list of all the
 * asset file names that match the given base name in that directory. Return
 * null if there's no such named asset. `platform` is used to identify
 * platform-specific assets, ex. `foo.ios.js` instead of a generic `foo.js`.
 */
export type ResolveAsset = (dirPath: string, assetName: string, extension: string) => null | undefined | ReadonlyArray<string>;
export interface _ResolutionContext_extraNodeModules {
  [$$Key$$: string]: string;
}
export interface _ResolutionContext_unstable_conditionsByPlatform {
  readonly [platform: string]: ReadonlyArray<string>;
}
export interface ResolutionContext {
  readonly allowHaste: boolean;
  readonly assetExts: ReadonlySet<string>;
  readonly customResolverOptions: CustomResolverOptions;
  readonly disableHierarchicalLookup: boolean;
  /**
   * Determine whether a regular file exists at the given path.
   *
   * @deprecated, prefer `fileSystemLookup`
   */
  readonly doesFileExist: DoesFileExist;
  readonly extraNodeModules?: null | _ResolutionContext_extraNodeModules;
  /** Is resolving for a development bundle. */
  readonly dev: boolean;
  /**
   * Get the parsed contents of the specified `package.json` file.
   */
  readonly getPackage: (packageJsonPath: string) => null | undefined | PackageJson;
  /**
   * Get the closest package scope, parsed `package.json` and relative subpath
   * for a given absolute candidate path (which need not exist), or null if
   * there is no package.json closer than the nearest node_modules directory.
   *
   * @deprecated See https://github.com/facebook/metro/commit/29c77bff31e2475a086bc3f04073f485da8f9ff0
   */
  readonly getPackageForModule: (absoluteModulePath: string) => null | undefined | PackageForModule;
  /**
   * The dependency descriptor, within the origin module, corresponding to the
   * current resolution request. This is provided for diagnostic purposes ONLY
   * and may not be used for resolution purposes.
   */
  readonly dependency?: TransformResultDependency;
  /**
   * Whether the dependency to be resolved was declared with an ESM import,
   * ("import x from 'y'" or "await import('z')"), or a CommonJS "require".
   * Corresponds to the criteria Node.js uses to assert an "import"
   * resolution condition, vs "require".
   *
   * Always equal to dependency.data.isESMImport where dependency is provided,
   * but may be used for resolution.
   */
  readonly isESMImport?: boolean;
  /**
   * Synchonously returns information about a given absolute path, including
   * whether it exists, whether it is a file or directory, and its absolute
   * real path.
   */
  readonly fileSystemLookup: FileSystemLookup;
  /**
   * The ordered list of fields to read in `package.json` to resolve a main
   * entry point based on the "browser" field spec.
   */
  readonly mainFields: ReadonlyArray<string>;
  /**
   * Full path of the module that is requiring or importing the module to be
   * resolved. This may not be the only place this dependency was found,
   * as resolutions can be cached.
   */
  readonly originModulePath: string;
  readonly nodeModulesPaths: ReadonlyArray<string>;
  readonly preferNativePlatform: boolean;
  readonly resolveAsset: ResolveAsset;
  readonly redirectModulePath: (modulePath: string) => string | false;
  /**
   * Given a name, this should return the full path to the file that provides
   * a Haste module of that name. Ex. for `Foo` it may return `/smth/Foo.js`.
   */
  readonly resolveHasteModule: (name: string) => null | undefined | string;
  /**
   * Given a name, this should return the full path to the package manifest that
   * provides a Haste package of that name. Ex. for `Foo` it may return
   * `/smth/Foo/package.json`.
   */
  readonly resolveHastePackage: (name: string) => null | undefined | string;
  readonly resolveRequest?: null | undefined | CustomResolver;
  readonly sourceExts: ReadonlyArray<string>;
  readonly unstable_conditionNames: ReadonlyArray<string>;
  readonly unstable_conditionsByPlatform: _ResolutionContext_unstable_conditionsByPlatform;
  readonly unstable_enablePackageExports: boolean;
  readonly unstable_incrementalResolution: boolean;
  readonly unstable_logWarning: (message: string) => void;
}
export interface CustomResolutionContext extends ResolutionContext {
  readonly resolveRequest: CustomResolver;
}
export type CustomResolver = (context: CustomResolutionContext, moduleName: string, platform: string | null) => Resolution;
export interface CustomResolverOptions {
  readonly [$$Key$$: string]: unknown;
}