import { InferOptionSchema } from "../../types/plugins.mjs";
import "../../types/index.mjs";
import { Statements } from "../access/types.mjs";
import "../access/index.mjs";
import { apiKeySchema } from "./schema.mjs";
import { Awaitable, GenericEndpointContext, HookEndpointContext } from "@better-auth/core";

//#region src/plugins/api-key/types.d.ts
interface ApiKeyOptions {
  /**
   * The header name to check for API key
   * @default "x-api-key"
   */
  apiKeyHeaders?: (string | string[]) | undefined;
  /**
   * Disable hashing of the API key.
   *
   * ⚠️ Security Warning: It's strongly recommended to not disable hashing.
   * Storing API keys in plaintext makes them vulnerable to database breaches, potentially exposing all your users' API keys.
   *
   * @default false
   */
  disableKeyHashing?: boolean | undefined;
  /**
   * The function to get the API key from the context
   */
  customAPIKeyGetter?: ((ctx: HookEndpointContext) => string | null) | undefined;
  /**
   * A custom function to validate the API key
   */
  customAPIKeyValidator?: ((options: {
    ctx: GenericEndpointContext;
    key: string;
  }) => Awaitable<boolean>) | undefined;
  /**
   * custom key generation function
   */
  customKeyGenerator?: (options: {
    /**
     * The length of the API key to generate
     */
    length: number;
    /**
     * The prefix of the API key to generate
     */
    prefix: string | undefined;
  }) => Awaitable<string>;
  /**
   * The configuration for storing the starting characters of the API key in the database.
   *
   * Useful if you want to display the starting characters of an API key in the UI.
   */
  startingCharactersConfig?: {
    /**
     * Whether to store the starting characters in the database. If false, we will set `start` to `null`.
     *
     * @default true
     */
    shouldStore?: boolean;
    /**
     * The length of the starting characters to store in the database.
     *
     * This includes the prefix length.
     *
     * @default 6
     */
    charactersLength?: number;
  } | undefined;
  /**
   * The length of the API key. Longer is better. Default is 64. (Doesn't include the prefix length)
   * @default 64
   */
  defaultKeyLength?: number | undefined;
  /**
   * The prefix of the API key.
   *
   * Note: We recommend you append an underscore to the prefix to make the prefix more identifiable. (eg `hello_`)
   */
  defaultPrefix?: string | undefined;
  /**
   * The maximum length of the prefix.
   *
   * @default 32
   */
  maximumPrefixLength?: number | undefined;
  /**
   * Whether to require a name for the API key.
   *
   * @default false
   */
  requireName?: boolean | undefined;
  /**
   * The minimum length of the prefix.
   *
   * @default 1
   */
  minimumPrefixLength?: number | undefined;
  /**
   * The maximum length of the name.
   *
   * @default 32
   */
  maximumNameLength?: number | undefined;
  /**
   * The minimum length of the name.
   *
   * @default 1
   */
  minimumNameLength?: number | undefined;
  /**
   * Whether to enable metadata for an API key.
   *
   * @default false
   */
  enableMetadata?: boolean | undefined;
  /**
   * Customize the key expiration.
   */
  keyExpiration?: {
    /**
     * The default expires time in milliseconds.
     *
     * If `null`, then there will be no expiration time.
     *
     * @default null
     */
    defaultExpiresIn?: number | null;
    /**
     * Whether to disable the expires time passed from the client.
     *
     * If `true`, the expires time will be based on the default values.
     *
     * @default false
     */
    disableCustomExpiresTime?: boolean;
    /**
     * The minimum expiresIn value allowed to be set from the client. in days.
     *
     * @default 1
     */
    minExpiresIn?: number;
    /**
     * The maximum expiresIn value allowed to be set from the client. in days.
     *
     * @default 365
     */
    maxExpiresIn?: number;
  } | undefined;
  /**
   * Default rate limiting options.
   */
  rateLimit?: {
    /**
     * Whether to enable rate limiting.
     *
     * @default true
     */
    enabled?: boolean;
    /**
     * The duration in milliseconds where each request is counted.
     *
     * Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset.
     *
     * @default 1000 * 60 * 60 * 24 // 1 day
     */
    timeWindow?: number;
    /**
     * Maximum amount of requests allowed within a window
     *
     * Once the `maxRequests` is reached, the request will be rejected until the `timeWindow` has passed, at which point the `timeWindow` will be reset.
     *
     * @default 10 // 10 requests per day
     */
    maxRequests?: number;
  } | undefined;
  /**
   * custom schema for the API key plugin
   */
  schema?: InferOptionSchema<ReturnType<typeof apiKeySchema>> | undefined;
  /**
   * An API Key can represent a valid session, so we automatically mock a session for the user if we find a valid API key in the request headers.
   *
   * ⚠︎ This is not recommended for production use, as it can lead to security issues.
   * @default false
   */
  enableSessionForAPIKeys?: boolean | undefined;
  /**
   * Permissions for the API key.
   */
  permissions?: {
    /**
     * The default permissions for the API key.
     */
    defaultPermissions?: Statements | ((userId: string, ctx: GenericEndpointContext) => Awaitable<Statements>);
  } | undefined;
  /**
   * Storage backend for API keys.
   *
   * - `"database"`: Store API keys in the database adapter (default)
   * - `"secondary-storage"`: Store API keys in the configured secondary storage (e.g., Redis)
   *
   * @default "database"
   */
  storage?: "database" | "secondary-storage" | undefined;
  /**
   * When `storage` is `"secondary-storage"`, enable fallback to database if key is not found in secondary storage.
   *
   * Useful for gradual migration from database to secondary storage.
   *
   * @default false
   */
  fallbackToDatabase?: boolean | undefined;
  /**
   * Custom storage methods for API keys.
   *
   * If provided, these methods will be used instead of `ctx.context.secondaryStorage`.
   * Custom methods take precedence over global secondary storage.
   *
   * Useful when you want to use a different storage backend specifically for API keys,
   * or when you need custom logic for storage operations.
   */
  customStorage?: {
    /**
     * Get a value from storage
     */
    get: (key: string) => Awaitable<unknown>;
    /**
     * Set a value in storage
     */
    set: (key: string, value: string, ttl?: number | undefined) => Awaitable<void | null | unknown>;
    /**
     * Delete a value from storage
     */
    delete: (key: string) => Awaitable<void | null | string>;
  } | undefined;
  /**
   * Defer non-critical updates (rate limiting counters, timestamps, remaining count)
   * to run after the response is sent using the global `advanced.backgroundTasks` handler.
   *
   * Requires `advanced.backgroundTasks.handler` to be configured in the main auth options.
   *
   * ⚠️ Warning: Enabling this introduces eventual consistency where the response
   * returns optimistic data before the database is updated. If the deferred update
   * fails, the database will have stale values. Only enable if your application
   * can tolerate this trade-off for improved latency.
   *
   * @default false
   */
  deferUpdates?: boolean | undefined;
}
type ApiKey = {
  /**
   * ID
   */
  id: string;
  /**
   * The name of the key
   */
  name: string | null;
  /**
   * Shows the first few characters of the API key, including the prefix.
   * This allows you to show those few characters in the UI to make it easier for users to identify the API key.
   */
  start: string | null;
  /**
   * The API Key prefix. Stored as plain text.
   */
  prefix: string | null;
  /**
   * The hashed API key value
   */
  key: string;
  /**
   * The owner of the user id
   */
  userId: string;
  /**
   * The interval in milliseconds between refills of the `remaining` count
   *
   * @example 3600000 // refill every hour (3600000ms = 1h)
   */
  refillInterval: number | null;
  /**
   * The amount to refill
   */
  refillAmount: number | null;
  /**
   * The last refill date
   */
  lastRefillAt: Date | null;
  /**
   * Sets if key is enabled or disabled
   *
   * @default true
   */
  enabled: boolean;
  /**
   * Whether the key has rate limiting enabled.
   */
  rateLimitEnabled: boolean;
  /**
   * The duration in milliseconds
   */
  rateLimitTimeWindow: number | null;
  /**
   * Maximum amount of requests allowed within a window
   */
  rateLimitMax: number | null;
  /**
   * The number of requests made within the rate limit time window
   */
  requestCount: number;
  /**
   * Remaining requests (every time API key is used this should updated and should be updated on refill as well)
   */
  remaining: number | null;
  /**
   * When last request occurred
   */
  lastRequest: Date | null;
  /**
   * Expiry date of a key
   */
  expiresAt: Date | null;
  /**
   * created at
   */
  createdAt: Date;
  /**
   * updated at
   */
  updatedAt: Date;
  /**
   * Extra metadata about the apiKey
   */
  metadata: Record<string, any> | null;
  /**
   * Permissions for the API key
   */
  permissions?: ({
    [key: string]: string[];
  } | null) | undefined;
};
//#endregion
export { ApiKey, ApiKeyOptions };
//# sourceMappingURL=types.d.mts.map