import ts, { CompilerOptions } from 'typescript';

interface File {
    type: "file";
    path: string;
}
interface Folder {
    type: "folder";
    path: string;
    children: Array<File | Folder>;
}
/**
 * An FSD root is an isolated folder structure that adheres to the rules of FSD.
 *
 * There can be several FSD roots in a project, they can also be arbitrarily nested.
 */
type FsdRoot = Folder;
type LayerName = "shared" | "entities" | "features" | "widgets" | "pages" | "app";
declare const layerSequence: Array<LayerName>;
declare const unslicedLayers: string[];
declare const conventionalSegmentNames: string[];
declare const crossReferenceToken = "@x";

/**
 * Extract layers from an FSD root.
 *
 * @returns A mapping of layer name to folder object.
 */
declare function getLayers(fsdRoot: Folder): Partial<Record<LayerName, Folder>>;
/**
 * Extract slices from a **sliced** layer.
 *
 * A folder is detected as a slice when it has at least one folder/file with a name of a conventional segment (`ui`, `api`, `model`, `lib`, `config`).
 * If your project contains slices that don't have those segments, you can provide additional segment names.
 *
 * @returns A mapping of slice name (potentially containing slashes) to folder object.
 */
declare function getSlices(slicedLayer: Folder, additionalSegmentNames?: Array<string>): Record<string, Folder>;
/**
 * Extract segments from a slice or an **unsliced** layer.
 *
 * @returns A mapping of segment name to folder or file object.
 */
declare function getSegments(sliceOrUnslicedLayer: Folder): Record<string, Folder | File>;
/**
 * Extract slices from all layers of an FSD root.
 *
 * A folder is detected as a slice when it has at least one folder/file with a name of a conventional segment (`ui`, `api`, `model`, `lib`, `config`).
 * If your project contains slices that don't have those segments, you can provide additional segment names.
 *
 * @returns A mapping of slice name (potentially containing slashes) to folder object with added layer name.
 */
declare function getAllSlices(fsdRoot: Folder, additionalSegmentNames?: Array<string>): Record<string, Folder & {
    layerName: string;
}>;
/**
 * Extract segments from all slices and layers of an FSD root.
 *
 * @returns A flat array of segments along with their name and location in the FSD root (layer, slice).
 */
declare function getAllSegments(fsdRoot: Folder): Array<{
    segment: Folder | File;
    segmentName: string;
    sliceName: string | null;
    layerName: LayerName;
}>;
/**
 * Determine if this layer is sliced.
 *
 * Only layers Shared and App are not sliced, the rest are.
 */
declare function isSliced(layerOrName: Folder | LayerName): boolean;
/**
 * Get the index (public API) of a slice or segment.
 *
 * When a segment is a file, it is its own index.
 * When a segment is a folder, it returns an array of index files within that folder.
 * Multiple index files (e.g., `index.client.js`, `index.server.js`) are supported.
 */
declare function getIndexes(fileOrFolder: File | Folder): File[];
/** Determine if a given file or folder is an index file. */
declare function isIndex(fileOrFolder: File | Folder): boolean;
/**
 * Check if a given file is a cross-import public API defined in the slice `inSlice` for the slice `forSlice` on a given layer.
 *
 * @example
 * const file = { path: "./src/entities/user/@x/product.ts", type: "file" }
 * isCrossImportPublicApi(file, { inSlice: "user", forSlice: "product", layerPath: "./src/entities" }) // true
 */
declare function isCrossImportPublicApi(file: File, { inSlice, forSlice, layerPath, }: {
    inSlice: string;
    forSlice: string;
    layerPath: string;
}): boolean;
/**
 * Determine if this folder is a slice.
 *
 * Slices are defined as folders that contain at least one segment.
 * Additional segment names can be provided if some slice in project contains only unconventional segments.
 */
declare function isSlice(folder: Folder, additionalSegmentNames?: Array<string>): boolean;

/**
 * Given a file name, an imported path, and a TSConfig object, produce a path to the imported file, relative to TypeScript's `baseUrl`.
 *
 * The resulting path uses OS-appropriate path separators.
 *
 * @example
 * ```tsx
 * // ./src/pages/home/ui/HomePage.tsx
 * import { Button } from "~/shared/ui";
 * ```
 *
 * ```json
 * // ./tsconfig.json
 * {
 *   "compilerOptions": {
 *     "moduleResolution": "Bundler",
 *     "baseUrl": ".",
 *     "paths": {
 *       "~/*": ["./src/*"],
 *     },
 *   },
 * }
 * ```
 *
 * ```tsx
 * resolveImport(
 *   "~/shared/ui",
 *   "./src/pages/home/ui/HomePage.tsx",
 *   { moduleResolution: "Bundler", baseUrl: ".", paths: { "~/*": ["./src/*"] } },
 *   fs.existsSync
 * );
 * ```
 * Expected output: `src/shared/ui/index.ts`
 */
declare function resolveImport(importedPath: string, importerPath: string, tsCompilerOptions: ImperfectCompilerOptions, fileExists: (path: string) => boolean, directoryExists?: (path: string) => boolean): string | null;
declare const imperfectKeys: {
    module: typeof ts.ModuleKind;
    moduleResolution: {
        node: ts.ModuleResolutionKind;
        Classic: ts.ModuleResolutionKind.Classic;
        NodeJs: ts.ModuleResolutionKind.NodeJs;
        Node10: ts.ModuleResolutionKind.NodeJs;
        Node16: ts.ModuleResolutionKind.Node16;
        NodeNext: ts.ModuleResolutionKind.NodeNext;
        Bundler: ts.ModuleResolutionKind.Bundler;
    };
    moduleDetection: typeof ts.ModuleDetectionKind;
    newLine: typeof ts.NewLineKind;
    target: typeof ts.ScriptTarget;
};
interface ImperfectCompilerOptions extends Omit<CompilerOptions, keyof typeof imperfectKeys> {
    module?: ts.ModuleKind | keyof typeof ts.ModuleKind;
    moduleResolution?: ts.ModuleResolutionKind | keyof typeof ts.ModuleResolutionKind | "node";
    moduleDetection?: ts.ModuleDetectionKind | keyof typeof ts.ModuleDetectionKind;
    newLine?: ts.NewLineKind | keyof typeof ts.NewLineKind;
    target?: ts.ScriptTarget | keyof typeof ts.ScriptTarget;
}

export { type File, type Folder, type FsdRoot, type LayerName, conventionalSegmentNames, crossReferenceToken, getAllSegments, getAllSlices, getIndexes, getLayers, getSegments, getSlices, isCrossImportPublicApi, isIndex, isSlice, isSliced, layerSequence, resolveImport, unslicedLayers };
