import { FilterPattern } from '@rollup/pluginutils';
import { TransformResult } from 'unplugin';
import { PreprocessorGroup } from 'svelte/types/compiler/preprocess';

type Awaitable<T> = T | PromiseLike<T>;
/**
 * Null or whatever
 */
type Nullable<T> = T | null | undefined;
/**
 * Array, or not yet
 */
type Arrayable<T> = T | Array<T>;
type FunctionArgs<Args extends any[] = any[], Return = void> = (...args: Args) => Return;
interface FunctionWrapperOptions<Args extends any[] = any[], This = any> {
    fn: FunctionArgs<Args, This>;
    args: Args;
    this_arg: This;
}
type AnyFn = (...args: any[]) => any;
type EventFilter<Args extends any[] = any[], This = any, Invoke extends AnyFn = AnyFn> = (invoke: Invoke, options: FunctionWrapperOptions<Args, This>) => ReturnType<Invoke> | Promise<ReturnType<Invoke>>;
interface ImportInfo {
    as?: string;
    name?: string;
    defaultImport?: boolean;
    from: string;
}
interface PublicPluginAPI {
    /**
     * Resolves a component using the configured resolvers.
     */
    findComponent: (name: string, filename?: string) => Promise<ImportInfo | undefined>;
    /**
     * Obtain an import statement for a resolved component.
     */
    stringifyImport: (info: ImportInfo) => string;
}
type ESLintGlobalsPropValue = boolean | "readonly" | "readable" | "writable" | "writeable";
interface ESLintrc {
    /**
     * @default true
     */
    enabled?: boolean;
    /**
     * Filepath to save the generated eslint config
     *
     * @default './.eslintrc-components.json'
     */
    filepath?: string;
    /**
     * @default true
     */
    globalsPropValue?: ESLintGlobalsPropValue;
}
/**
 * Plugin options.
 */
interface Options {
    /**
     * RegExp or glob to match files to be transformed
     */
    include?: FilterPattern;
    /**
     * RegExp or glob to match files to NOT be transformed
     */
    exclude?: FilterPattern;
    /**
     * Relative paths to the directory to search for components.
     * @default 'src/components'
     */
    dirs?: string | string[];
    /**
     * Valid file extensions for components.
     * @default ['svelte']
     */
    extensions?: string | string[];
    /**
     * Glob patterns to match file names to be detected as components.
     *
     * When specified, the `dirs` and `extensions` options will be ignored.
     */
    globs?: string | string[];
    /**
     * Search for subdirectories
     * @default true
     */
    deep?: boolean;
    /**
     * Allow subdirectories as namespace prefix for components
     * @default false
     */
    directoryAsNamespace?: boolean;
    /**
     * Collapse same prefixes (case-insensitive) of folders and components
     * to prevent duplication inside namespaced component name
     *
     * Works when `directoryAsNamespace: true`
     * @default false
     */
    collapseSamePrefixes?: boolean;
    /**
     * Subdirectory paths for ignoring namespace prefixes
     *
     * Works when `directoryAsNamespace: true`
     * @default "[]"
     */
    globalNamespaces?: string[];
    /**
     * Apply custom transform over the path for importing
     */
    importPathTransform?: (path: string) => string | undefined;
    /**
     * Generate TypeScript declaration for global components
     *
     * Accept boolean or a path related to project root
     *
     * @default true
     */
    dts?: boolean | string;
    /**
     * Accept a svelte pre-processor
     */
    preprocess?: PreprocessorGroup | null;
    /**
     * Do not emit warning on component overriding
     *
     * @default false
     */
    allowOverrides?: boolean;
    /**
     * Import Third-Party Components
     **/
    external?: ExternalImport[];
    /**
     * Generate corresponding .eslintrc-auto-import.json file.
     */
    eslintrc?: ESLintrc;
}
interface ExternalImport {
    from: string;
    names: string[];
    defaultImport: boolean;
}
type ComponentResolveResult = Awaitable<string | ImportInfo | null | undefined | void>;
type ComponentResolverFunction = (name: string) => ComponentResolveResult;
interface ComponentResolverObject {
    type: "component";
    resolve: ComponentResolverFunction;
}
type ComponentResolver = ComponentResolverFunction | ComponentResolverObject;
type ResolvedOptions = Omit<Required<Options>, "resolvers" | "extensions" | "dirs" | "globalComponentsDeclaration"> & {
    resolvers: ComponentResolverObject[];
    extensions: string[];
    dirs: string[];
    resolvedDirs: string[];
    globs: string[];
    dts: string | false;
    root: string;
};
type Transformer = (code: string, id: string, path: string, query: Record<string, string>) => Awaitable<TransformResult | null>;

export { AnyFn, Arrayable, ComponentResolveResult, ComponentResolver, ComponentResolverFunction, ComponentResolverObject, ESLintGlobalsPropValue, ESLintrc, EventFilter, ExternalImport, FunctionArgs, FunctionWrapperOptions, ImportInfo, Nullable, Options, PublicPluginAPI, ResolvedOptions, Transformer };
