import { AwsClient } from "aws4fetch";
import { NextRequest } from "next/server";

//#region src/core/providers/providers.d.ts

/**
 * Cloud Storage Providers System
 *
 * This provides a clean way to configure different cloud storage providers
 * with environment-based configuration and type-safe initialization.
 *
 * Supported Providers:
 * - AWS S3, Cloudflare R2, DigitalOcean Spaces, MinIO
 *
 * Future Provider Support:
 * - Enterprise: Azure Blob, IBM Cloud, Oracle OCI
 * - Cost-Optimized: Wasabi, Backblaze B2, Storj DCS
 * - Specialized: Telnyx, Tigris, Cloudian HyperStore
 */
interface BaseProviderConfig {
  provider: string;
  region?: string;
  bucket: string;
  acl?: string;
  customDomain?: string;
  forcePathStyle?: boolean;
}
interface AWSProviderConfig extends BaseProviderConfig {
  provider: "aws";
  accessKeyId: string;
  secretAccessKey: string;
  region: string;
  sessionToken?: string;
}
interface CloudflareR2Config extends BaseProviderConfig {
  provider: "cloudflare-r2";
  accountId: string;
  accessKeyId: string;
  secretAccessKey: string;
  region?: "auto";
  endpoint?: string;
}
interface DigitalOceanSpacesConfig extends BaseProviderConfig {
  provider: "digitalocean-spaces";
  accessKeyId: string;
  secretAccessKey: string;
  region: string;
  endpoint?: string;
}
interface MinIOConfig extends BaseProviderConfig {
  provider: "minio";
  endpoint: string;
  accessKeyId: string;
  secretAccessKey: string;
  useSSL?: boolean;
  port?: number;
}
interface AzureBlobConfig extends BaseProviderConfig {
  provider: "azure-blob";
  accountName: string;
  accessKeyId: string;
  secretAccessKey: string;
  endpoint?: string;
}
interface IBMCloudConfig extends BaseProviderConfig {
  provider: "ibm-cloud";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
  serviceInstanceId?: string;
}
interface OracleOCIConfig extends BaseProviderConfig {
  provider: "oracle-oci";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
  namespace?: string;
}
interface WasabiConfig extends BaseProviderConfig {
  provider: "wasabi";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint?: string;
}
interface BackblazeB2Config extends BaseProviderConfig {
  provider: "backblaze-b2";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
}
interface StorjDCSConfig extends BaseProviderConfig {
  provider: "storj-dcs";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint?: string;
}
interface TelnyxStorageConfig extends BaseProviderConfig {
  provider: "telnyx-storage";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
}
interface TigrisDataConfig extends BaseProviderConfig {
  provider: "tigris-data";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
  region?: "auto";
}
interface CloudianHyperStoreConfig extends BaseProviderConfig {
  provider: "cloudian-hyperstore";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
}
interface GoogleCloudStorageConfig extends BaseProviderConfig {
  provider: "gcs";
  projectId: string;
  keyFilename?: string;
  credentials?: object;
}
interface S3CompatibleConfig extends BaseProviderConfig {
  provider: "s3-compatible";
  accessKeyId: string;
  secretAccessKey: string;
  endpoint: string;
}
type ProviderConfig = AWSProviderConfig | CloudflareR2Config | DigitalOceanSpacesConfig | MinIOConfig | AzureBlobConfig | IBMCloudConfig | OracleOCIConfig | WasabiConfig | BackblazeB2Config | StorjDCSConfig | TelnyxStorageConfig | TigrisDataConfig | CloudianHyperStoreConfig | GoogleCloudStorageConfig | S3CompatibleConfig;
declare const PROVIDER_SPECS: {
  readonly aws: {
    readonly provider: "aws";
    readonly configKeys: {
      readonly region: readonly ["AWS_REGION", "S3_REGION"];
      readonly bucket: readonly ["AWS_S3_BUCKET", "S3_BUCKET", "S3_BUCKET_NAME"];
      readonly accessKeyId: readonly ["AWS_ACCESS_KEY_ID", "S3_ACCESS_KEY_ID"];
      readonly secretAccessKey: readonly ["AWS_SECRET_ACCESS_KEY", "S3_SECRET_ACCESS_KEY"];
      readonly sessionToken: readonly ["AWS_SESSION_TOKEN"];
      readonly acl: readonly ["S3_ACL"];
      readonly customDomain: readonly ["S3_CUSTOM_DOMAIN"];
    };
    readonly defaults: {
      readonly region: "us-east-1";
      readonly acl: "private";
    };
  };
  readonly cloudflareR2: {
    readonly provider: "cloudflare-r2";
    readonly configKeys: {
      readonly accountId: readonly ["CLOUDFLARE_ACCOUNT_ID", "R2_ACCOUNT_ID"];
      readonly bucket: readonly ["CLOUDFLARE_R2_BUCKET", "R2_BUCKET"];
      readonly accessKeyId: readonly ["CLOUDFLARE_R2_ACCESS_KEY_ID", "R2_ACCESS_KEY_ID"];
      readonly secretAccessKey: readonly ["CLOUDFLARE_R2_SECRET_ACCESS_KEY", "R2_SECRET_ACCESS_KEY"];
      readonly endpoint: readonly ["CLOUDFLARE_R2_ENDPOINT", "R2_ENDPOINT"];
      readonly customDomain: readonly ["R2_CUSTOM_DOMAIN"];
      readonly acl: readonly [];
    };
    readonly defaults: {
      readonly region: "auto";
      readonly acl: "private";
    };
    readonly customLogic: (config: any, computed: any) => {
      endpoint: any;
    };
  };
  readonly digitalOceanSpaces: {
    readonly provider: "digitalocean-spaces";
    readonly configKeys: {
      readonly region: readonly ["DO_SPACES_REGION", "DIGITALOCEAN_SPACES_REGION"];
      readonly bucket: readonly ["DO_SPACES_BUCKET", "DIGITALOCEAN_SPACES_BUCKET"];
      readonly accessKeyId: readonly ["DO_SPACES_ACCESS_KEY_ID", "DIGITALOCEAN_SPACES_ACCESS_KEY_ID"];
      readonly secretAccessKey: readonly ["DO_SPACES_SECRET_ACCESS_KEY", "DIGITALOCEAN_SPACES_SECRET_ACCESS_KEY"];
      readonly endpoint: readonly ["DO_SPACES_ENDPOINT", "DIGITALOCEAN_SPACES_ENDPOINT"];
      readonly customDomain: readonly ["DO_SPACES_CUSTOM_DOMAIN"];
      readonly acl: readonly [];
    };
    readonly defaults: {
      readonly region: "nyc3";
      readonly acl: "private";
    };
    readonly customLogic: (config: any, computed: any) => {
      endpoint: any;
    };
  };
  readonly minio: {
    readonly provider: "minio";
    readonly configKeys: {
      readonly endpoint: readonly ["MINIO_ENDPOINT"];
      readonly bucket: readonly ["MINIO_BUCKET"];
      readonly accessKeyId: readonly ["MINIO_ACCESS_KEY_ID", "MINIO_ACCESS_KEY"];
      readonly secretAccessKey: readonly ["MINIO_SECRET_ACCESS_KEY", "MINIO_SECRET_KEY"];
      readonly region: readonly ["MINIO_REGION"];
      readonly customDomain: readonly ["MINIO_CUSTOM_DOMAIN"];
      readonly acl: readonly [];
    };
    readonly defaults: {
      readonly endpoint: "localhost:9000";
      readonly region: "us-east-1";
      readonly acl: "private";
    };
    readonly customLogic: (config: any, computed: any) => {
      useSSL: any;
      port: number | undefined;
    };
  };
  readonly gcs: {
    readonly provider: "gcs";
    readonly configKeys: {
      readonly projectId: readonly ["GOOGLE_CLOUD_PROJECT_ID", "GCS_PROJECT_ID"];
      readonly bucket: readonly ["GCS_BUCKET", "GOOGLE_CLOUD_STORAGE_BUCKET"];
      readonly keyFilename: readonly ["GOOGLE_APPLICATION_CREDENTIALS", "GCS_KEY_FILE"];
      readonly region: readonly ["GCS_REGION"];
      readonly customDomain: readonly ["GCS_CUSTOM_DOMAIN"];
      readonly acl: readonly [];
    };
    readonly defaults: {
      readonly region: "us-central1";
      readonly acl: "private";
    };
    readonly customLogic: (config: any) => {
      credentials: any;
    };
  };
  readonly s3Compatible: {
    readonly provider: "s3-compatible";
    readonly configKeys: {
      readonly endpoint: readonly ["S3_ENDPOINT", "S3_COMPATIBLE_ENDPOINT"];
      readonly bucket: readonly ["S3_BUCKET", "S3_BUCKET_NAME"];
      readonly accessKeyId: readonly ["S3_ACCESS_KEY_ID", "ACCESS_KEY_ID"];
      readonly secretAccessKey: readonly ["S3_SECRET_ACCESS_KEY", "SECRET_ACCESS_KEY"];
      readonly region: readonly ["S3_REGION", "REGION"];
      readonly customDomain: readonly ["S3_CUSTOM_DOMAIN"];
      readonly acl: readonly ["S3_ACL"];
    };
    readonly defaults: {
      readonly region: "us-east-1";
      readonly acl: "private";
      readonly forcePathStyle: true;
    };
  };
};
type ProviderSpecsType = typeof PROVIDER_SPECS;
type ProviderType = keyof ProviderSpecsType;
/**
 * Maps each provider type to its corresponding configuration interface
 * This enables type-safe provider configuration in createUploadConfig().provider()
 */
type ProviderConfigMap = {
  aws: Partial<Omit<AWSProviderConfig, "provider">>;
  cloudflareR2: Partial<Omit<CloudflareR2Config, "provider">>;
  digitalOceanSpaces: Partial<Omit<DigitalOceanSpacesConfig, "provider">>;
  minio: Partial<Omit<MinIOConfig, "provider">>;
  gcs: Partial<Omit<GoogleCloudStorageConfig, "provider">>;
  s3Compatible: Partial<Omit<S3CompatibleConfig, "provider">>;
};
/**
 * Type-safe provider configuration function
 * Usage: createProvider("aws", { bucket: "my-bucket", region: "us-west-2" })
 */
declare function createProvider<T extends ProviderType>(type: T, config?: ProviderConfigMap[T]): ProviderConfig;
declare function validateProviderConfig(config: ProviderConfig): {
  valid: boolean;
  errors: string[];
};
declare function getProviderEndpoint(config: ProviderConfig): string;
//#endregion
//#region src/core/schema.d.ts
interface S3FileConstraints {
  maxSize?: string | number;
  minSize?: string | number;
  allowedTypes?: string[];
  allowedExtensions?: string[];
  required?: boolean;
}
interface S3ArrayConstraints {
  min?: number;
  max?: number;
  length?: number;
}
interface S3ValidationContext {
  file: File;
  fieldName: string;
  allFiles?: Record<string, File | File[]>;
}
interface S3ValidationResult {
  success: boolean;
  error?: {
    code: string;
    message: string;
    path: string[];
  };
  data?: any;
}
interface S3TransformContext<T = any> {
  file: File;
  metadata?: Record<string, any>;
  originalData: T;
}
declare abstract class S3Schema<TInput = any, TOutput = TInput> {
  protected _constraints: Record<string, any>;
  protected _transforms: Array<(ctx: S3TransformContext<TInput>) => Promise<any> | any>;
  protected _validators: Array<(ctx: S3ValidationContext) => S3ValidationResult | Promise<S3ValidationResult>>;
  protected _optional: boolean;
  abstract _type: string;
  abstract _parse(input: unknown): S3ValidationResult | Promise<S3ValidationResult>;
  validate(input: unknown, context?: Partial<S3ValidationContext>): Promise<S3ValidationResult>;
  optional(): S3Schema<TInput, TOutput | undefined>;
  transform<TNewOutput>(transformer: (ctx: S3TransformContext<TOutput>) => Promise<TNewOutput> | TNewOutput): S3Schema<TInput, TNewOutput>;
  refine(validator: (ctx: S3ValidationContext) => boolean | Promise<boolean>, message: string): this;
  protected abstract _clone(): this;
}
declare class S3FileSchema extends S3Schema<File, File> {
  protected constraints: S3FileConstraints;
  _type: "file";
  constructor(constraints?: S3FileConstraints);
  _parse(input: unknown): S3ValidationResult;
  max(size: string | number): S3FileSchema;
  min(size: string | number): S3FileSchema;
  types(allowedTypes: string[]): S3FileSchema;
  extensions(allowedExtensions: string[]): S3FileSchema;
  array(constraints?: S3ArrayConstraints): S3ArraySchema<this>;
  protected _clone(): this;
  middleware<TMetadata>(middleware: (ctx: {
    req: any;
    file: {
      name: string;
      size: number;
      type: string;
    };
    metadata: any;
  }) => Promise<TMetadata> | TMetadata): S3Route<this, TMetadata>;
  onUploadStart(hook: (ctx: {
    file: {
      name: string;
      size: number;
      type: string;
    };
    metadata: any;
  }) => Promise<void> | void): S3Route<this, any>;
  onUploadComplete(hook: (ctx: {
    file: {
      name: string;
      size: number;
      type: string;
    };
    metadata: any;
    url?: string;
    key?: string;
  }) => Promise<void> | void): S3Route<this, any>;
  onUploadError(hook: (ctx: {
    file: {
      name: string;
      size: number;
      type: string;
    };
    metadata: any;
    error: Error;
  }) => Promise<void> | void): S3Route<this, any>;
  private _parseSize;
  private _formatSize;
}
declare class S3ImageSchema extends S3FileSchema {
  constructor(constraints?: S3FileConstraints);
  formats(formats: string[]): S3ImageSchema;
  max(size: string | number): S3ImageSchema;
  min(size: string | number): S3ImageSchema;
  types(allowedTypes: string[]): S3ImageSchema;
  extensions(allowedExtensions: string[]): S3ImageSchema;
  array(constraints?: S3ArrayConstraints): S3ArraySchema<this>;
  protected _clone(): this;
}
declare class S3ArraySchema<T extends S3Schema> extends S3Schema<File[], File[]> {
  private elementSchema;
  private arrayConstraints;
  _type: "array";
  constructor(elementSchema: T, arrayConstraints?: S3ArrayConstraints);
  _parse(input: unknown): Promise<S3ValidationResult>;
  min(count: number): S3ArraySchema<T>;
  max(count: number): S3ArraySchema<T>;
  length(count: number): S3ArraySchema<T>;
  protected _clone(): this;
}
declare class S3ObjectSchema<T extends Record<string, S3Schema>> extends S3Schema<{ [K in keyof T]: T[K] extends S3Schema<any, infer U> ? U : never }, { [K in keyof T]: T[K] extends S3Schema<any, infer U> ? U : never }> {
  private shape;
  _type: "object";
  constructor(shape: T);
  _parse(input: unknown): Promise<S3ValidationResult>;
  protected _clone(): this;
}
type InferS3Input<T extends S3Schema> = T extends S3Schema<infer I, any> ? I : never;
type InferS3Output<T extends S3Schema> = T extends S3Schema<any, infer O> ? O : never;
//#endregion
//#region src/core/storage/client.d.ts
/**
 * Creates and caches an AWS client instance using aws4fetch
 */
declare function createS3Client(uploadConfig?: UploadConfig): AwsClient;
/**
 * Resets the AWS client instance (useful for testing)
 */
declare function resetS3Client(): void;
interface PresignedUrlOptions {
  key: string;
  contentType?: string;
  contentLength?: number;
  expiresIn?: number;
  metadata?: Record<string, string>;
}
interface PresignedUrlResult {
  url: string;
  key: string;
  fields?: Record<string, string>;
}
/**
 * Generates a presigned URL for downloading/viewing a file from S3
 */

interface FileKeyOptions {
  originalName: string;
  userId?: string;
  prefix?: string;
  preserveExtension?: boolean;
  addTimestamp?: boolean;
  addRandomId?: boolean;
}
/**
 * Generates a unique file key for S3 storage
 */

interface UploadProgress {
  loaded: number;
  total: number;
  percentage: number;
  key: string;
  progress?: number;
  uploadSpeed?: number;
  eta?: number;
}
type ProgressCallback = (progress: UploadProgress) => void;
/**
 * Uploads a file directly to S3 with progress tracking
 * Note: This is for server-side uploads. Client-side uploads use presigned URLs.
 */

interface ListFilesOptions {
  prefix?: string;
  maxFiles?: number;
  includeMetadata?: boolean;
  sortBy?: "key" | "size" | "modified";
  sortOrder?: "asc" | "desc";
}
interface PaginatedListOptions extends ListFilesOptions {
  pageSize?: number;
  continuationToken?: string;
}
interface FileInfo {
  key: string;
  url: string;
  size: number;
  contentType: string;
  lastModified: Date;
  etag: string;
  metadata?: Record<string, string>;
}
interface ListFilesResult {
  files: FileInfo[];
  continuationToken?: string;
  isTruncated: boolean;
  totalCount?: number;
}
/**
 * Lists files in the bucket with optional filtering and pagination
 */

interface FileInfoResult {
  key: string;
  info: FileInfo | null;
  error?: string;
}
interface FileValidationResult {
  valid: boolean;
  errors: string[];
  warnings: string[];
  info: FileInfo;
}
interface ValidationRules {
  maxSize?: number;
  minSize?: number;
  allowedTypes?: string[];
  requiredExtensions?: string[];
  customValidators?: ((info: FileInfo) => boolean | string)[];
}
/**
 * Gets detailed information about a file
 */

interface DeleteFilesResult {
  deleted: string[];
  errors: DeleteError[];
}
interface DeleteError {
  key: string;
  code: string;
  message: string;
}
interface DeleteByPrefixResult {
  filesFound: number;
  deleted: string[];
  errors: DeleteError[];
  dryRun: boolean;
}
//#endregion
//#region src/core/storage/storage-api.d.ts
declare class StorageInstance {
  private readonly config;
  constructor(config: UploadConfig);
  /**
   * Get the current configuration (read-only)
   */
  getConfig(): Readonly<UploadConfig>;
  /**
   * Get provider information
   */
  getProviderInfo(): {
    provider: "aws" | "cloudflare-r2" | "digitalocean-spaces" | "minio" | "azure-blob" | "ibm-cloud" | "oracle-oci" | "wasabi" | "backblaze-b2" | "storj-dcs" | "telnyx-storage" | "tigris-data" | "cloudian-hyperstore" | "gcs" | "s3-compatible";
    bucket: string;
    region: string | undefined;
  };
  list: {
    files: (options?: ListFilesOptions) => Promise<FileInfo[]>;
    paginated: (options?: PaginatedListOptions) => Promise<ListFilesResult>;
    byExtension: (extension: string, prefix?: string) => Promise<FileInfo[]>;
    bySize: (minSize?: number, maxSize?: number, prefix?: string) => Promise<FileInfo[]>;
    byDate: (fromDate?: Date, toDate?: Date, prefix?: string) => Promise<FileInfo[]>;
    directories: (prefix?: string) => Promise<string[]>;
    paginatedGenerator: (options?: PaginatedListOptions) => AsyncGenerator<FileInfo[], any, any>;
  };
  metadata: {
    getInfo: (key: string) => Promise<FileInfo>;
    getBatch: (keys: string[]) => Promise<FileInfoResult[]>;
    getSize: (key: string) => Promise<number>;
    getContentType: (key: string) => Promise<string>;
    getLastModified: (key: string) => Promise<Date>;
    getCustom: (key: string) => Promise<Record<string, string>>;
    setCustom: (key: string, metadata: Record<string, string>) => Promise<void>;
  };
  download: {
    presignedUrl: (key: string, expiresIn?: number) => Promise<string>;
    url: (key: string) => string;
  };
  upload: {
    file: (file: File | Buffer, key: string, options?: any) => Promise<string>;
    presignedUrl: (options: PresignedUrlOptions) => Promise<PresignedUrlResult>;
    presignedBatch: (requests: PresignedUrlOptions[]) => Promise<PresignedUrlResult[]>;
    generateKey: (options: FileKeyOptions) => string;
  };
  validation: {
    exists: (key: string) => Promise<boolean>;
    existsWithInfo: (key: string) => Promise<FileInfo | null>;
    validateFile: (key: string, rules: ValidationRules) => Promise<FileValidationResult>;
    validateFiles: (keys: string[], rules: ValidationRules) => Promise<FileValidationResult[]>;
    connection: () => Promise<{
      success: boolean;
      error?: string;
    }>;
  };
  delete: {
    file: (key: string) => Promise<void>;
    files: (keys: string[]) => Promise<DeleteFilesResult>;
    byPrefix: (prefix: string, options?: {
      dryRun?: boolean;
      maxFiles?: number;
    }) => Promise<DeleteByPrefixResult>;
  };
}
/**
 * Create a new storage instance with the given configuration
 */
declare function createStorage(config: UploadConfig): StorageInstance;
//#endregion
//#region src/core/config/upload-config.d.ts
declare function createS3Instance(config: UploadConfig): {
  readonly file: (constraints?: S3FileConstraints) => S3FileSchema;
  readonly image: (constraints?: S3FileConstraints) => S3ImageSchema;
  readonly object: <T extends Record<string, any>>(shape: T) => S3ObjectSchema<T>;
  readonly createRouter: <TRoutes extends Record<string, any>>(routes: TRoutes) => S3Router<{ [K in keyof TRoutes]: TRoutes[K] extends S3Route<any, any> ? TRoutes[K] : S3Route<any, any> }>;
};
interface UploadConfig {
  provider: ProviderConfig;
  debug?: boolean;
  enableMetrics?: boolean;
  defaults?: {
    maxFileSize?: string | number;
    allowedFileTypes?: string[];
    acl?: string;
    metadata?: Record<string, any>;
  };
  paths?: {
    prefix?: string;
    generateKey?: (file: {
      name: string;
      type: string;
    }, metadata: any) => string;
  };
  security?: {
    requireAuth?: boolean;
    allowedOrigins?: string[];
    rateLimiting?: {
      maxUploads?: number;
      windowMs?: number;
    };
  };
  hooks?: {
    onUploadStart?: (ctx: {
      file: any;
      metadata: any;
    }) => Promise<void> | void;
    onUploadComplete?: (ctx: {
      file: any;
      url: string;
      metadata: any;
    }) => Promise<void> | void;
    onUploadError?: (ctx: {
      file: any;
      error: Error;
      metadata: any;
    }) => Promise<void> | void;
  };
}
declare class UploadConfigBuilder {
  private config;
  /**
   * Set the storage provider with type-safe configuration
   */
  provider(providerConfig: ProviderConfig): UploadConfigBuilder;
  provider<T extends ProviderType>(type: T, config: ProviderConfigMap[T]): UploadConfigBuilder;
  /**
   * Set default file constraints
   */
  defaults(defaults: UploadConfig["defaults"]): UploadConfigBuilder;
  /**
   * Configure file paths and key generation
   */
  paths(paths: UploadConfig["paths"]): UploadConfigBuilder;
  /**
   * Configure security settings
   */
  security(security: UploadConfig["security"]): UploadConfigBuilder;
  /**
   * Add lifecycle hooks
   */
  hooks(hooks: UploadConfig["hooks"]): UploadConfigBuilder;
  /**
   * Enable debug mode
   */
  debug(enabled?: boolean): UploadConfigBuilder;
  /**
   * Enable metrics collection
   */
  metrics(enabled?: boolean): UploadConfigBuilder;
  /**
   * Build the final configuration and return configured instances
   */
  build(): UploadInitResult;
}
interface UploadInitResult {
  config: UploadConfig;
  storage: StorageInstance;
  s3: ReturnType<typeof createS3Instance>;
}
/**
 * Create a new upload configuration builder
 * This is the recommended way to configure pushduck
 */
declare function createUploadConfig(): UploadConfigBuilder;
//#endregion
//#region src/core/router/router-v2.d.ts
interface S3RouteContext {
  req: NextRequest;
  metadata?: Record<string, any>;
}
interface S3FileMetadata$1 {
  name: string;
  size: number;
  type: string;
}
interface S3MiddlewareContext extends S3RouteContext {
  file: S3FileMetadata$1;
}
interface S3LifecycleContext<T = any> {
  file: S3FileMetadata$1;
  metadata: T;
  url?: string;
  key?: string;
}
type S3Middleware<TInput = any, TOutput = any> = (ctx: S3MiddlewareContext & {
  metadata: TInput;
}) => Promise<TOutput> | TOutput;
type S3LifecycleHook<T = any> = (ctx: S3LifecycleContext<T>) => Promise<void> | void;
interface PathContext<TMetadata = any> {
  file: {
    name: string;
    type: string;
  };
  metadata: TMetadata;
  globalConfig: {
    prefix?: string;
    generateKey?: (file: {
      name: string;
      type: string;
    }, metadata: any) => string;
  };
  routeName: string;
}
interface S3RoutePathConfig<TMetadata = any> {
  prefix?: string;
  generateKey?: (ctx: PathContext<TMetadata>) => string;
  suffix?: string;
}
declare class S3Route<TSchema extends S3Schema = S3Schema, TMetadata = any> {
  private schema;
  private config;
  constructor(schema: TSchema, config?: S3RouteConfig<TMetadata>);
  middleware<TNewMetadata>(middleware: S3Middleware<TMetadata, TNewMetadata>): S3Route<TSchema, TNewMetadata>;
  paths(paths: S3RoutePathConfig<TMetadata>): this;
  onUploadStart(hook: S3LifecycleHook<TMetadata>): this;
  onUploadProgress(hook: (ctx: S3LifecycleContext<TMetadata> & {
    progress: number;
  }) => Promise<void> | void): this;
  onUploadComplete(hook: S3LifecycleHook<TMetadata>): this;
  onUploadError(hook: (ctx: S3LifecycleContext<TMetadata> & {
    error: Error;
  }) => Promise<void> | void): this;
  _getConfig(): S3RouteConfig<TMetadata> & {
    schema: TSchema;
  };
}
interface S3RouteConfig<TMetadata = any> {
  middleware?: S3Middleware<any, any>[];
  paths?: S3RoutePathConfig<TMetadata>;
  onUploadStart?: S3LifecycleHook<TMetadata>;
  onUploadProgress?: (ctx: S3LifecycleContext<TMetadata> & {
    progress: number;
  }) => Promise<void> | void;
  onUploadComplete?: S3LifecycleHook<TMetadata>;
  onUploadError?: (ctx: S3LifecycleContext<TMetadata> & {
    error: Error;
  }) => Promise<void> | void;
}
type S3RouterDefinition = Record<string, S3Route<any, any>>;
declare class S3Router<TRoutes extends S3RouterDefinition> {
  private config;
  private routes;
  constructor(routes: TRoutes, config: UploadConfig);
  getRoute<K extends keyof TRoutes>(routeName: K): TRoutes[K] | undefined;
  getRouteNames(): (keyof TRoutes)[];
  get handlers(): {
    GET: (request: Request) => Promise<Response>;
    POST: (request: Request) => Promise<Response>;
  };
  generatePresignedUrls<K extends keyof TRoutes>(routeName: K, req: NextRequest, files: S3FileMetadata$1[]): Promise<PresignedUrlResponse[]>;
  handleUploadComplete<K extends keyof TRoutes>(routeName: K, req: NextRequest, completions: UploadCompletion[]): Promise<CompletionResponse[]>;
}
interface PresignedUrlResponse {
  success: boolean;
  file: S3FileMetadata$1;
  presignedUrl?: string;
  key?: string;
  metadata?: any;
  error?: string;
}
interface UploadCompletion {
  key: string;
  file: S3FileMetadata$1;
  metadata?: any;
}
interface CompletionResponse {
  success: boolean;
  key: string;
  url?: string;
  file?: S3FileMetadata$1;
  error?: string;
}
/**
 * ✅ Config-aware router factory
 * Creates router with explicit config dependency
 */
declare function createS3RouterWithConfig<TRoutes extends S3RouterDefinition>(routes: TRoutes, config: UploadConfig): S3Router<TRoutes>;
type InferRouterRoutes<T> = T extends S3Router<infer TRoutes> ? TRoutes : never;
type InferRouteInput<T> = T extends S3Route<infer TSchema, any> ? InferS3Input<TSchema> : never;
type InferRouteOutput<T> = T extends S3Route<infer TSchema, any> ? InferS3Output<TSchema> : never;
type InferRouteMetadata<T> = T extends S3Route<any, infer TMetadata> ? TMetadata : never;
type GetRoute<TRouter, TRouteName> = TRouter extends S3Router<infer TRoutes> ? TRouteName extends keyof TRoutes ? TRoutes[TRouteName] : never : never;
//#endregion
//#region src/types/index.d.ts
/**
 * Centralized Type Definitions for pushduck
 *
 * This file consolidates all type definitions to prevent circular dependencies
 * and provide a single source of truth for types used across the library.
 */
interface S3UploadedFile {
  id: string;
  name: string;
  size: number;
  type: string;
  status: "pending" | "uploading" | "success" | "error";
  progress: number;
  url?: string;
  key?: string;
  error?: string;
  file?: File;
  uploadStartTime?: number;
  uploadSpeed?: number;
  eta?: number;
}
interface S3FileMetadata {
  name: string;
  size: number;
  type: string;
}
interface UploadRouteConfig {
  endpoint?: string;
  onStart?: (files: S3FileMetadata[]) => void | Promise<void>;
  onSuccess?: (results: S3UploadedFile[]) => void | Promise<void>;
  onError?: (error: Error) => void;
  onProgress?: (progress: number) => void;
  disabled?: boolean;
  autoUpload?: boolean;
}
type S3RouteUploadConfig = UploadRouteConfig;
type RouteUploadOptions = UploadRouteConfig;
interface S3RouteUploadResult {
  files: S3UploadedFile[];
  uploadFiles: (files: File[]) => Promise<void>;
  reset: () => void;
  isUploading: boolean;
  errors: string[];
  progress?: number;
  uploadSpeed?: number;
  eta?: number;
}
interface ClientConfig {
  endpoint: string;
  fetcher?: (input: RequestInfo, init?: RequestInit) => Promise<Response>;
  defaultOptions?: RouteUploadOptions;
}
interface TypedUploadedFile<TOutput = any> extends S3UploadedFile {
  metadata?: TOutput;
  constraints?: {
    maxSize?: string;
    formats?: readonly string[];
    dimensions?: {
      width?: number;
      height?: number;
    };
  };
  routeName?: string;
}
interface TypedRouteHook<TRouter = any, TRouteName extends string = string> {
  files: TypedUploadedFile[];
  uploadFiles: (files: File[], metadata?: any) => Promise<any[]>;
  reset: () => void;
  isUploading: boolean;
  errors: string[];
  routeName: TRouteName;
  progress?: number;
  uploadSpeed?: number;
  eta?: number;
}
type RouterRouteNames<T> = T extends S3Router<infer TRoutes> ? keyof TRoutes : never;
type InferClientRouter<T> = T extends S3Router<infer TRoutes> ? { readonly [K in keyof TRoutes]: (options?: RouteUploadOptions) => TypedRouteHook<T, K extends string ? K : string> } : never;
//#endregion
export { AWSProviderConfig, BaseProviderConfig, ClientConfig, CloudflareR2Config, DeleteByPrefixResult, DeleteError, DeleteFilesResult, DigitalOceanSpacesConfig, FileInfo, FileInfoResult, FileKeyOptions, FileValidationResult, GetRoute, GoogleCloudStorageConfig, InferClientRouter, InferRouteInput, InferRouteMetadata, InferRouteOutput, InferRouterRoutes, InferS3Input, InferS3Output, ListFilesOptions, ListFilesResult, MinIOConfig, PaginatedListOptions, PresignedUrlOptions, PresignedUrlResult, ProgressCallback, ProviderConfig, ProviderType, RouterRouteNames, S3ArraySchema, S3FileConstraints, S3FileMetadata, S3FileSchema, S3ImageSchema, S3LifecycleContext, S3LifecycleHook, S3Middleware, S3MiddlewareContext, S3ObjectSchema, S3Route, S3RouteContext, S3RouteUploadConfig, S3RouteUploadResult, S3Router, S3RouterDefinition, S3Schema, S3UploadedFile, StorageInstance, TypedRouteHook, TypedUploadedFile, UploadConfig, UploadConfigBuilder, UploadInitResult, UploadProgress, UploadRouteConfig, ValidationRules, createProvider, createS3Client, createS3RouterWithConfig, createStorage, createUploadConfig, getProviderEndpoint, resetS3Client, validateProviderConfig };