import { z } from 'zod';

/**
 * Beta Access Management Interface
 *
 * Provides a vendor-agnostic way to manage beta/early-access programs.
 * Handles invite codes, access gating, settings, and analytics across
 * all DLL Platform applications.
 *
 * Features:
 * - Beta mode settings (mode, require code, custom message)
 * - Invite code management (create, validate, consume, revoke)
 * - Multi-use codes with usage tracking and expiration
 * - Profile tagging (beta tester flag, join date)
 * - Analytics (usage stats, per-code reports)
 * - Live toggling (closed beta → open beta → public launch)
 *
 * @example
 * ```typescript
 * import { MemoryBeta } from '@digilogiclabs/platform-core';
 *
 * const beta = new MemoryBeta();
 *
 * // Check if beta is active
 * const settings = await beta.getSettings();
 * if (settings.requireInviteCode) {
 *   const result = await beta.validateCode('BETA2026');
 *   if (result.valid) {
 *     await beta.consumeCode('BETA2026', 'user_123');
 *   }
 * }
 *
 * // Create invite codes
 * const codes = await beta.createCodes({
 *   count: 10,
 *   prefix: 'DLL',
 *   maxUses: 5,
 *   createdBy: 'admin',
 * });
 *
 * // Transition to public launch
 * await beta.updateSettings({ betaMode: false, requireInviteCode: false });
 * ```
 */
/** Beta program settings */
interface BetaSettings {
    /** Whether the app is in beta mode (shows beta messaging) */
    betaMode: boolean;
    /** Whether an invite code is required to sign up */
    requireInviteCode: boolean;
    /** Custom message to display during beta */
    betaMessage: string;
}
/** Options for updating beta settings */
interface UpdateBetaSettingsOptions {
    betaMode?: boolean;
    requireInviteCode?: boolean;
    betaMessage?: string;
    updatedBy?: string;
}
/** A beta invite code */
interface BetaInviteCode {
    /** Unique identifier */
    id: string;
    /** The invite code string (normalized to uppercase) */
    code: string;
    /** Maximum number of times this code can be used */
    maxUses: number;
    /** Current number of times this code has been used */
    currentUses: number;
    /** Optional expiration date */
    expiresAt: Date | null;
    /** Who created this code */
    createdBy: string;
    /** Admin notes about this code */
    notes: string;
    /** Whether this code is active (soft delete) */
    isActive: boolean;
    /** When this code was created */
    createdAt: Date;
}
/** Options for creating invite codes */
interface CreateBetaCodesOptions {
    /** Number of codes to generate (max 50) */
    count?: number;
    /** Prefix for generated codes (e.g., 'DLL' → 'DLL-A1B2C3D4') */
    prefix?: string;
    /** Specific code string (for named codes like 'BETA2026') */
    code?: string;
    /** Maximum uses per code (default: 1) */
    maxUses?: number;
    /** Optional expiration date */
    expiresAt?: Date;
    /** Who is creating the codes */
    createdBy: string;
    /** Admin notes */
    notes?: string;
}
/** Filter for listing invite codes */
type BetaCodeStatus = "unused" | "partial" | "exhausted" | "expired" | "revoked";
interface ListBetaCodesOptions {
    /** Filter by status */
    status?: BetaCodeStatus;
    /** Filter by active state */
    isActive?: boolean;
    /** Pagination offset */
    offset?: number;
    /** Pagination limit */
    limit?: number;
}
/** Result of validating a beta code (read-only, does not consume) */
interface BetaValidationResult {
    /** Whether the code is valid */
    valid: boolean;
    /** Human-readable message */
    message: string;
    /** The normalized code (if valid) */
    code?: string;
    /** Remaining uses (if valid) */
    remainingUses?: number;
}
/** Result of consuming a beta code */
interface BetaConsumeResult {
    /** Whether the code was successfully consumed */
    success: boolean;
    /** Human-readable message */
    message: string;
}
/** Beta tester profile metadata */
interface BetaTester {
    /** User identifier */
    userId: string;
    /** The invite code they used */
    inviteCode: string;
    /** Whether they are flagged as a beta tester */
    isBetaTester: boolean;
    /** When they joined beta */
    betaJoinedAt: Date;
}
/** Aggregate beta program statistics */
interface BetaStats {
    /** Total number of beta testers */
    totalBetaTesters: number;
    /** Total invite codes created */
    totalCodes: number;
    /** Number of active (usable) codes */
    activeCodes: number;
    /** Total uses across all codes */
    totalUses: number;
    /** Total remaining capacity across all codes */
    totalRemaining: number;
    /** Earliest beta signup */
    firstBetaSignup: Date | null;
    /** Most recent beta signup */
    latestBetaSignup: Date | null;
}
/** Per-code usage report */
interface BetaCodeUsageReport {
    /** The invite code */
    code: string;
    /** Admin notes */
    notes: string;
    /** Maximum uses */
    maxUses: number;
    /** Current uses */
    currentUses: number;
    /** Remaining uses */
    remainingUses: number;
    /** Usage percentage (0-100) */
    usagePercent: number;
    /** Whether the code is active */
    isActive: boolean;
    /** Expiration date */
    expiresAt: Date | null;
    /** Creation date */
    createdAt: Date;
}
/** Configuration for beta adapters */
interface BetaConfig {
    /** Default beta mode on initialization */
    defaultBetaMode?: boolean;
    /** Default require invite code on initialization */
    defaultRequireInviteCode?: boolean;
    /** Default beta message */
    defaultBetaMessage?: string;
    /** Code prefix for generated codes (e.g., 'DLL', 'WIAN') */
    codePrefix?: string;
    /** Maximum codes per createCodes call (default: 50) */
    maxCodesPerBatch?: number;
}
interface IBeta {
    /** Get current beta program settings */
    getSettings(): Promise<BetaSettings>;
    /** Update beta program settings (live toggle, no redeploy needed) */
    updateSettings(options: UpdateBetaSettingsOptions): Promise<void>;
    /** Create one or more invite codes */
    createCodes(options: CreateBetaCodesOptions): Promise<BetaInviteCode[]>;
    /** List invite codes with optional filtering */
    listCodes(options?: ListBetaCodesOptions): Promise<BetaInviteCode[]>;
    /** Get a specific invite code by its code string */
    getCode(code: string): Promise<BetaInviteCode | null>;
    /** Revoke an invite code (soft delete — sets isActive to false) */
    revokeCode(code: string): Promise<void>;
    /**
     * Validate an invite code (read-only, does not consume).
     * If requireInviteCode is false, always returns { valid: true }.
     */
    validateCode(code: string): Promise<BetaValidationResult>;
    /**
     * Consume an invite code for a user (increments usage, tags user).
     * Should be called after successful signup, not before.
     */
    consumeCode(code: string, userId: string): Promise<BetaConsumeResult>;
    /** Check if a user is a beta tester */
    isBetaTester(userId: string): Promise<boolean>;
    /** Get beta tester details for a user */
    getBetaTester(userId: string): Promise<BetaTester | null>;
    /** List all beta testers */
    listBetaTesters(options?: {
        offset?: number;
        limit?: number;
    }): Promise<BetaTester[]>;
    /** Get aggregate beta program statistics */
    getStats(): Promise<BetaStats>;
    /** Get per-code usage reports */
    getCodeUsageReports(): Promise<BetaCodeUsageReport[]>;
    /** Check beta service health */
    healthCheck(): Promise<boolean>;
}
/** Generate a random hex code with prefix (e.g., 'DLL-A1B2C3D4') */
declare function generateBetaCode(prefix?: string): string;
/** Normalize a code for comparison (trim + uppercase) */
declare function normalizeBetaCode(code: string): string;
/** Generate a unique ID for beta records */
declare function generateBetaId(): string;
declare class MemoryBeta implements IBeta {
    private settings;
    private codes;
    private testers;
    private config;
    constructor(config?: BetaConfig);
    getSettings(): Promise<BetaSettings>;
    updateSettings(options: UpdateBetaSettingsOptions): Promise<void>;
    createCodes(options: CreateBetaCodesOptions): Promise<BetaInviteCode[]>;
    listCodes(options?: ListBetaCodesOptions): Promise<BetaInviteCode[]>;
    getCode(code: string): Promise<BetaInviteCode | null>;
    revokeCode(code: string): Promise<void>;
    validateCode(code: string): Promise<BetaValidationResult>;
    consumeCode(code: string, userId: string): Promise<BetaConsumeResult>;
    isBetaTester(userId: string): Promise<boolean>;
    getBetaTester(userId: string): Promise<BetaTester | null>;
    listBetaTesters(options?: {
        offset?: number;
        limit?: number;
    }): Promise<BetaTester[]>;
    getStats(): Promise<BetaStats>;
    getCodeUsageReports(): Promise<BetaCodeUsageReport[]>;
    healthCheck(): Promise<boolean>;
    /** Clear all data (for testing) */
    clear(): void;
    /** Get the number of stored codes */
    get codeCount(): number;
    /** Get the number of beta testers */
    get testerCount(): number;
}

/**
 * API Utilities
 *
 * Framework-agnostic error codes, error class, response types,
 * and database error mapping for consistent API behavior across apps.
 */
/** Standard API error codes */
declare const ApiErrorCode: {
    readonly VALIDATION_ERROR: "VALIDATION_ERROR";
    readonly UNAUTHORIZED: "UNAUTHORIZED";
    readonly FORBIDDEN: "FORBIDDEN";
    readonly NOT_FOUND: "NOT_FOUND";
    readonly CONFLICT: "CONFLICT";
    readonly RATE_LIMIT_EXCEEDED: "RATE_LIMIT_EXCEEDED";
    readonly INTERNAL_ERROR: "INTERNAL_ERROR";
    readonly DATABASE_ERROR: "DATABASE_ERROR";
    readonly EXTERNAL_SERVICE_ERROR: "EXTERNAL_SERVICE_ERROR";
    readonly CONFIGURATION_ERROR: "CONFIGURATION_ERROR";
};
type ApiErrorCodeType = (typeof ApiErrorCode)[keyof typeof ApiErrorCode];
/** Custom API Error class with status code and error code */
declare class ApiError extends Error {
    readonly statusCode: number;
    readonly code: ApiErrorCodeType;
    readonly details?: unknown;
    constructor(statusCode: number, message: string, code?: ApiErrorCodeType, details?: unknown);
}
/** Type guard for ApiError */
declare function isApiError(error: unknown): error is ApiError;
/** Pre-built error factories */
declare const CommonApiErrors: {
    unauthorized: (msg?: string) => ApiError;
    forbidden: (msg?: string) => ApiError;
    notFound: (resource?: string) => ApiError;
    conflict: (msg?: string) => ApiError;
    rateLimitExceeded: (msg?: string) => ApiError;
    validationError: (details?: unknown) => ApiError;
    internalError: (msg?: string) => ApiError;
};
/** PostgreSQL error code → HTTP status mapping */
declare const PG_ERROR_MAP: Record<string, {
    status: number;
    code: ApiErrorCodeType;
    message: string;
}>;
/**
 * Classify any error into a standardized shape.
 * Framework-agnostic — returns a plain object, not an HTTP response.
 */
declare function classifyError(error: unknown, isDev?: boolean): {
    status: number;
    body: {
        error: string;
        code: string;
        details?: unknown;
    };
};
/** Standard success response shape */
interface ApiSuccessResponse<T = unknown> {
    success: true;
    data: T;
    message?: string;
    timestamp?: string;
}
/** Standard paginated response shape */
interface ApiPaginatedResponse<T = unknown> extends ApiSuccessResponse<T[]> {
    pagination: {
        page: number;
        limit: number;
        total: number;
        totalPages: number;
        hasMore: boolean;
    };
}
/** Build a pagination metadata object */
declare function buildPagination(page: number, limit: number, total: number): {
    page: number;
    limit: number;
    total: number;
    totalPages: number;
    hasMore: boolean;
};

/**
 * Keycloak Authentication Utilities
 *
 * Framework-agnostic helpers for working with Keycloak OIDC tokens.
 * Used by Next.js apps (Auth.js middleware + API routes) and .NET services
 * share the same role model — these helpers ensure consistent behavior.
 *
 * Edge-runtime compatible: uses atob() for JWT decoding, not Buffer.
 */
/**
 * Keycloak provider configuration for Auth.js / NextAuth.
 * Everything needed to configure the Keycloak OIDC provider.
 */
interface KeycloakConfig {
    /** Keycloak issuer URL (e.g. https://auth.example.com/realms/my-realm) */
    issuer: string;
    /** OAuth client ID registered in Keycloak */
    clientId: string;
    /** OAuth client secret */
    clientSecret: string;
}
/**
 * Token set returned by Keycloak after authentication or refresh.
 */
interface KeycloakTokenSet {
    accessToken: string;
    refreshToken?: string;
    idToken?: string;
    /** Expiry as epoch milliseconds */
    expiresAt: number;
    /** Parsed realm roles (filtered, no Keycloak defaults) */
    roles: string[];
}
/**
 * Result of a token refresh attempt.
 */
type TokenRefreshResult = {
    ok: true;
    tokens: KeycloakTokenSet;
} | {
    ok: false;
    error: string;
};
/**
 * Default Keycloak roles that should be filtered out when checking
 * application-level roles. These are always present and not meaningful
 * for authorization decisions.
 */
declare const KEYCLOAK_DEFAULT_ROLES: readonly ["offline_access", "uma_authorization"];
/**
 * Parse realm roles from a Keycloak JWT access token.
 *
 * Supports two token formats:
 * - `realm_roles` (flat array) — Custom client mapper configuration
 * - `realm_access.roles` (nested) — Keycloak default format
 *
 * Uses atob() for Edge runtime compatibility (not Buffer.from).
 * Filters out Keycloak default roles automatically.
 *
 * @param accessToken - Raw JWT string from Keycloak
 * @param additionalDefaultRoles - Extra role names to filter (e.g. realm-specific defaults)
 * @returns Array of meaningful role names
 *
 * @example
 * ```typescript
 * const roles = parseKeycloakRoles(account.access_token)
 * // ['admin', 'editor']
 *
 * // With realm-specific defaults
 * const roles = parseKeycloakRoles(token, ['default-roles-my-realm'])
 * ```
 */
declare function parseKeycloakRoles(accessToken: string | undefined | null, additionalDefaultRoles?: string[]): string[];
/**
 * Check if a user has a specific role.
 *
 * @example
 * ```typescript
 * if (hasRole(session.user.roles, 'admin')) {
 *   // grant access
 * }
 * ```
 */
declare function hasRole(roles: string[] | undefined | null, role: string): boolean;
/**
 * Check if a user has ANY of the specified roles (OR logic).
 *
 * @example
 * ```typescript
 * if (hasAnyRole(session.user.roles, ['admin', 'editor'])) {
 *   // grant access
 * }
 * ```
 */
declare function hasAnyRole(roles: string[] | undefined | null, requiredRoles: string[]): boolean;
/**
 * Check if a user has ALL of the specified roles (AND logic).
 *
 * @example
 * ```typescript
 * if (hasAllRoles(session.user.roles, ['admin', 'billing'])) {
 *   // grant access to billing admin
 * }
 * ```
 */
declare function hasAllRoles(roles: string[] | undefined | null, requiredRoles: string[]): boolean;
/**
 * Check if a token needs refreshing.
 *
 * @param expiresAt - Token expiry as epoch milliseconds
 * @param bufferMs - Refresh this many ms before actual expiry (default: 60s)
 * @returns true if the token should be refreshed
 */
declare function isTokenExpired(expiresAt: number | undefined | null, bufferMs?: number): boolean;
/**
 * Build the URLSearchParams for a Keycloak token refresh request.
 *
 * This is the body for POST to `{issuer}/protocol/openid-connect/token`.
 * Framework-agnostic — use with fetch(), axios, or any HTTP client.
 *
 * @example
 * ```typescript
 * const params = buildTokenRefreshParams(config, refreshToken)
 * const response = await fetch(`${config.issuer}/protocol/openid-connect/token`, {
 *   method: 'POST',
 *   headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
 *   body: params,
 * })
 * ```
 */
declare function buildTokenRefreshParams(config: KeycloakConfig, refreshToken: string): URLSearchParams;
/**
 * Get the Keycloak token endpoint URL for a given issuer.
 */
declare function getTokenEndpoint(issuer: string): string;
/**
 * Get the Keycloak end session (logout) endpoint URL.
 */
declare function getEndSessionEndpoint(issuer: string): string;
/**
 * Perform a token refresh against Keycloak and parse the result.
 *
 * Returns a discriminated union — check `result.ok` before accessing tokens.
 * Automatically parses roles from the new access token.
 *
 * @example
 * ```typescript
 * const result = await refreshKeycloakToken(config, currentRefreshToken)
 * if (result.ok) {
 *   token.accessToken = result.tokens.accessToken
 *   token.roles = result.tokens.roles
 * } else {
 *   // Force re-login
 *   token.error = 'RefreshTokenError'
 * }
 * ```
 */
declare function refreshKeycloakToken(config: KeycloakConfig, refreshToken: string, additionalDefaultRoles?: string[]): Promise<TokenRefreshResult>;

/**
 * Next.js Auth.js + Keycloak Configuration Builder
 *
 * Generates Auth.js callbacks for Keycloak OIDC integration.
 * Handles JWT token storage, role parsing, token refresh, and session mapping.
 *
 * Edge-runtime compatible: uses only atob() and fetch(), no Node.js-only APIs.
 *
 * @example
 * ```typescript
 * // auth.config.ts (Edge-compatible)
 * import { buildKeycloakCallbacks } from '@digilogiclabs/platform-core'
 * import Keycloak from 'next-auth/providers/keycloak'
 *
 * const callbacks = buildKeycloakCallbacks({
 *   issuer: process.env.AUTH_KEYCLOAK_ISSUER!,
 *   clientId: process.env.AUTH_KEYCLOAK_ID!,
 *   clientSecret: process.env.AUTH_KEYCLOAK_SECRET!,
 *   defaultRoles: ['default-roles-my-realm'],
 * })
 *
 * export const authConfig = {
 *   providers: [Keycloak({ ... })],
 *   session: { strategy: 'jwt' },
 *   callbacks,
 * }
 * ```
 */
interface KeycloakCallbacksConfig {
    /** Keycloak issuer URL */
    issuer: string;
    /** OAuth client ID */
    clientId: string;
    /** OAuth client secret */
    clientSecret: string;
    /** Realm-specific default roles to filter (e.g. ['default-roles-my-realm']) */
    defaultRoles?: string[];
    /** Enable debug logging (default: NODE_ENV === 'development') */
    debug?: boolean;
}
/**
 * Extended JWT token shape used by the Keycloak callbacks.
 * These fields are added to the Auth.js JWT token during sign-in and refresh.
 */
interface KeycloakJwtFields {
    id?: string;
    accessToken?: string;
    refreshToken?: string;
    idToken?: string;
    accessTokenExpires?: number;
    roles?: string[];
    error?: string;
}
interface AuthCookiesConfig {
    /** Production cookie domain (e.g. '.digilogiclabs.com'). Omit for default domain. */
    domain?: string;
    /** Include session token cookie config (default: true) */
    sessionToken?: boolean;
    /** Include callback URL cookie config (default: true) */
    callbackUrl?: boolean;
}
/**
 * Build Auth.js cookie configuration for cross-domain OIDC.
 *
 * Handles the common pattern of configuring cookies to work across
 * www and non-www domains (e.g. digilogiclabs.com and www.digilogiclabs.com).
 *
 * PKCE and state cookies are always included for OAuth security.
 * Session token and callback URL cookies are included by default.
 *
 * @example
 * ```typescript
 * import { buildAuthCookies } from '@digilogiclabs/platform-core'
 *
 * export const authConfig = {
 *   cookies: buildAuthCookies({ domain: '.digilogiclabs.com' }),
 *   // ...
 * }
 * ```
 */
declare function buildAuthCookies(config?: AuthCookiesConfig): Record<string, {
    name: string;
    options: {
        httpOnly: boolean;
        sameSite: "lax";
        path: string;
        secure: boolean;
        domain: string | undefined;
    };
}>;
interface RedirectCallbackConfig {
    /** Allow www variant redirects (e.g. www.example.com ↔ example.com) */
    allowWwwVariant?: boolean;
}
/**
 * Build a standard Auth.js redirect callback.
 *
 * Handles common redirect patterns:
 * - Relative URLs → prefixed with baseUrl
 * - Same-origin URLs → allowed
 * - www variant URLs → optionally allowed
 * - Everything else → baseUrl
 *
 * @example
 * ```typescript
 * import { buildRedirectCallback } from '@digilogiclabs/platform-core'
 *
 * export const authConfig = {
 *   callbacks: {
 *     redirect: buildRedirectCallback({ allowWwwVariant: true }),
 *   },
 * }
 * ```
 */
declare function buildRedirectCallback(config?: RedirectCallbackConfig): ({ url, baseUrl }: {
    url: string;
    baseUrl: string;
}) => Promise<string>;
/**
 * Build Auth.js JWT and session callbacks for Keycloak.
 *
 * Returns an object with `jwt` and `session` callbacks that handle:
 * - Storing Keycloak tokens on initial sign-in
 * - Parsing realm roles from the access token
 * - Automatic token refresh when expired
 * - Mapping tokens/roles to the session object
 *
 * The callbacks are Edge-runtime compatible.
 */
declare function buildKeycloakCallbacks(config: KeycloakCallbacksConfig): {
    /**
     * JWT callback — stores Keycloak tokens and handles refresh.
     *
     * Compatible with Auth.js v5 JWT callback signature.
     */
    jwt({ token, user, account, }: {
        token: any;
        user?: any;
        account?: any;
    }): Promise<any>;
    /**
     * Session callback — maps JWT fields to the session object.
     *
     * Compatible with Auth.js v5 session callback signature.
     */
    session({ session, token }: {
        session: any;
        token: any;
    }): Promise<any>;
};

/**
 * API Security Types & Helpers
 *
 * Framework-agnostic types and utilities for building composable
 * API security wrappers. These define the shared contract that
 * framework-specific implementations (Next.js, Express, .NET) follow.
 *
 * The actual wrappers (withPublicApi, withAdminApi, etc.) live in each
 * app because they depend on framework-specific request/response types.
 * This module provides the shared types and logic they all use.
 */
/**
 * How a request was authenticated.
 * Used by audit logging and authorization decisions.
 */
type AuthMethod = "session" | "bearer_token" | "api_key" | "webhook_signature" | "cron_secret" | "none";
/**
 * Audit configuration for a secured route.
 * Tells the security wrapper what to log.
 */
interface RouteAuditConfig {
    /** The action being performed (e.g. 'game.server.create') */
    action: string;
    /** The resource type being acted on (e.g. 'game_server') */
    resourceType: string;
}
/**
 * Rate limit preset configuration.
 * Matches the structure used by all apps.
 */
interface RateLimitPreset {
    /** Maximum requests allowed in the window */
    limit: number;
    /** Window duration in seconds */
    windowSeconds: number;
    /** Higher limit for authenticated users */
    authenticatedLimit?: number;
    /** Block duration when limit exceeded (seconds) */
    blockDurationSeconds?: number;
}
/**
 * Standard rate limit presets shared across all apps.
 *
 * Apps can extend with their own domain-specific presets:
 * ```typescript
 * const APP_RATE_LIMITS = {
 *   ...StandardRateLimitPresets,
 *   gameServerCreate: { limit: 5, windowSeconds: 3600, blockDurationSeconds: 3600 },
 * }
 * ```
 */
declare const StandardRateLimitPresets: {
    /** General API: 100/min, 200/min authenticated */
    readonly apiGeneral: {
        readonly limit: 100;
        readonly windowSeconds: 60;
        readonly authenticatedLimit: 200;
    };
    /** Admin operations: 100/min (admins are trusted) */
    readonly adminAction: {
        readonly limit: 100;
        readonly windowSeconds: 60;
    };
    /** AI/expensive operations: 20/hour, 50/hour authenticated */
    readonly aiRequest: {
        readonly limit: 20;
        readonly windowSeconds: 3600;
        readonly authenticatedLimit: 50;
    };
    /** Auth attempts: 5/15min with 15min block */
    readonly authAttempt: {
        readonly limit: 5;
        readonly windowSeconds: 900;
        readonly blockDurationSeconds: 900;
    };
    /** Contact/public forms: 10/hour */
    readonly publicForm: {
        readonly limit: 10;
        readonly windowSeconds: 3600;
        readonly blockDurationSeconds: 1800;
    };
    /** Checkout/billing: 10/hour with 1hr block */
    readonly checkout: {
        readonly limit: 10;
        readonly windowSeconds: 3600;
        readonly blockDurationSeconds: 3600;
    };
};
/**
 * Configuration for a secured API handler.
 *
 * This is the framework-agnostic config shape. Each framework's
 * wrapper (withPublicApi, withAdminApi, etc.) maps to this structure.
 */
interface ApiSecurityConfig {
    /** Whether authentication is required */
    requireAuth: boolean;
    /** Whether admin role is required */
    requireAdmin: boolean;
    /** Required roles (user must have at least one) */
    requireRoles?: string[];
    /** Allow legacy bearer token as alternative to session auth */
    allowBearerToken?: boolean;
    /** Rate limit preset name or custom config */
    rateLimit?: string | RateLimitPreset;
    /** Audit logging config */
    audit?: RouteAuditConfig;
    /** Human-readable operation name for logging */
    operation?: string;
    /** Skip rate limiting */
    skipRateLimit?: boolean;
    /** Skip audit logging */
    skipAudit?: boolean;
}
/**
 * Minimal session shape that all auth systems provide.
 * Maps to Auth.js Session, .NET ClaimsPrincipal, etc.
 */
interface SecuritySession {
    user: {
        id: string;
        email?: string | null;
        name?: string | null;
        roles?: string[];
    };
}
/**
 * Context available to secured route handlers after all security
 * checks have passed. Framework wrappers extend this with their
 * own fields (e.g. NextRequest, validated body, etc.).
 */
interface ApiSecurityContext {
    /** Authenticated session (null for public routes or token auth) */
    session: SecuritySession | null;
    /** How the request was authenticated */
    authMethod: AuthMethod;
    /** Whether the user has admin privileges */
    isAdmin: boolean;
    /** Request correlation ID */
    requestId: string;
}
/**
 * Determine the appropriate rate limit key for a request.
 *
 * Priority: user ID > email > IP address.
 * Authenticated users get their own bucket (and potentially higher limits).
 *
 * @param session - Current session (if any)
 * @param clientIp - Client IP address
 * @returns { identifier, isAuthenticated }
 */
declare function resolveRateLimitIdentifier(session: SecuritySession | null, clientIp: string): {
    identifier: string;
    isAuthenticated: boolean;
};
/**
 * Extract the client IP from standard proxy headers.
 *
 * Checks (in order): CF-Connecting-IP, X-Real-IP, X-Forwarded-For.
 * Use this to ensure consistent IP extraction across all apps.
 *
 * @param getHeader - Header getter function
 * @returns Client IP or 'unknown'
 */
declare function extractClientIp(getHeader: (name: string) => string | null | undefined): string;
/**
 * Build the standard rate limit response headers.
 *
 * @returns Headers object with X-RateLimit-* headers
 */
declare function buildRateLimitHeaders(limit: number, remaining: number, resetAtMs: number): Record<string, string>;
/**
 * Build a standard error response body.
 * Ensures consistent error shape across all apps.
 */
declare function buildErrorBody(error: string, extra?: Record<string, unknown>): Record<string, unknown>;
/**
 * Pre-built security configurations for common route types.
 *
 * Use these as the base for framework-specific wrappers:
 * ```typescript
 * // In your app's api-security.ts
 * export function withPublicApi(config, handler) {
 *   return createSecureHandler({
 *     ...WrapperPresets.public,
 *     ...config,
 *   }, handler)
 * }
 * ```
 */
declare const WrapperPresets: {
    /** Public route: no auth, rate limited */
    readonly public: {
        readonly requireAuth: false;
        readonly requireAdmin: false;
        readonly rateLimit: "apiGeneral";
    };
    /** Authenticated route: requires session */
    readonly authenticated: {
        readonly requireAuth: true;
        readonly requireAdmin: false;
        readonly rateLimit: "apiGeneral";
    };
    /** Admin route: requires session with admin role */
    readonly admin: {
        readonly requireAuth: true;
        readonly requireAdmin: true;
        readonly rateLimit: "adminAction";
    };
    /** Legacy admin: accepts session OR bearer token */
    readonly legacyAdmin: {
        readonly requireAuth: true;
        readonly requireAdmin: true;
        readonly allowBearerToken: true;
        readonly rateLimit: "adminAction";
    };
    /** AI/expensive: requires auth, strict rate limit */
    readonly ai: {
        readonly requireAuth: true;
        readonly requireAdmin: false;
        readonly rateLimit: "aiRequest";
    };
    /** Cron: no rate limit, admin-level access */
    readonly cron: {
        readonly requireAuth: true;
        readonly requireAdmin: false;
        readonly skipRateLimit: true;
        readonly skipAudit: false;
    };
};

/**
 * Common Validation Schemas
 *
 * Reusable Zod schemas for request validation across all apps.
 * These are the building blocks — apps compose them into
 * route-specific schemas for their own domain logic.
 *
 * Requires `zod` as a peer dependency (already in platform-core).
 */

/** Validated, normalized email address */
declare const EmailSchema: z.ZodString;
/** Password with minimum security requirements */
declare const PasswordSchema: z.ZodString;
/** URL-safe slug (lowercase alphanumeric + hyphens) */
declare const SlugSchema: z.ZodString;
/** Phone number (international format, flexible) */
declare const PhoneSchema: z.ZodString;
/** Human name (letters, spaces, hyphens, apostrophes) */
declare const PersonNameSchema: z.ZodString;
/**
 * Create a text schema that blocks HTML tags and links.
 * Use for user-facing text fields (contact forms, comments, etc.)
 *
 * @param options - Customize min/max length and error messages
 *
 * @example
 * ```typescript
 * const MessageSchema = createSafeTextSchema({ min: 10, max: 1000 })
 * const CommentSchema = createSafeTextSchema({ max: 500, allowUrls: true })
 * ```
 */
declare function createSafeTextSchema(options?: {
    min?: number;
    max?: number;
    allowHtml?: boolean;
    allowUrls?: boolean;
    fieldName?: string;
}): z.ZodType<string, string>;
/** Standard pagination query parameters */
declare const PaginationSchema: z.ZodObject<{
    page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
    limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
    sortBy: z.ZodOptional<z.ZodString>;
    sortOrder: z.ZodDefault<z.ZodEnum<{
        asc: "asc";
        desc: "desc";
    }>>;
}, z.core.$strip>;
/** Date range filter (ISO 8601 datetime strings) */
declare const DateRangeSchema: z.ZodObject<{
    startDate: z.ZodString;
    endDate: z.ZodString;
}, z.core.$strip>;
/** Search query with optional filters */
declare const SearchQuerySchema: z.ZodObject<{
    query: z.ZodString;
    page: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
    limit: z.ZodDefault<z.ZodCoercedNumber<unknown>>;
}, z.core.$strip>;
/** Login credentials */
declare const LoginSchema: z.ZodObject<{
    email: z.ZodString;
    password: z.ZodString;
}, z.core.$strip>;
/** Signup with optional name */
declare const SignupSchema: z.ZodObject<{
    email: z.ZodString;
    password: z.ZodString;
    name: z.ZodOptional<z.ZodString>;
}, z.core.$strip>;
type EmailInput = z.infer<typeof EmailSchema>;
type PaginationInput = z.infer<typeof PaginationSchema>;
type DateRangeInput = z.infer<typeof DateRangeSchema>;
type SearchQueryInput = z.infer<typeof SearchQuerySchema>;
type LoginInput = z.infer<typeof LoginSchema>;
type SignupInput = z.infer<typeof SignupSchema>;

/**
 * Feature Flag System
 *
 * Generic, type-safe feature flag builder for staged rollout.
 * Each app defines its own flags; this module provides the
 * infrastructure for evaluating them by environment.
 *
 * @example
 * ```typescript
 * // Define your app's flags
 * const flags = createFeatureFlags({
 *   STRIPE_PAYMENTS: {
 *     development: true,
 *     staging: true,
 *     production: { envVar: 'ENABLE_PAYMENTS' },
 *   },
 *   PUBLIC_SIGNUP: {
 *     development: true,
 *     staging: false,
 *     production: { envVar: 'ENABLE_PUBLIC_SIGNUP' },
 *   },
 *   AI_FEATURES: {
 *     development: true,
 *     staging: { envVar: 'ENABLE_AI' },
 *     production: false,
 *   },
 * })
 *
 * // Evaluate at runtime
 * const resolved = flags.resolve() // reads NODE_ENV + DEPLOYMENT_STAGE
 * if (resolved.STRIPE_PAYMENTS) { ... }
 *
 * // Check a single flag
 * if (flags.isEnabled('AI_FEATURES')) { ... }
 * ```
 */
type DeploymentStage = "development" | "staging" | "preview" | "production";
/**
 * How a flag is resolved in a given environment.
 * - `true` / `false` — hardcoded on/off
 * - `{ envVar: string }` — read from environment variable (truthy = "true")
 * - `{ envVar: string, default: boolean }` — with fallback
 */
type FlagValue = boolean | {
    envVar: string;
    default?: boolean;
};
/**
 * Flag definition across deployment stages.
 */
interface FlagDefinition {
    development: FlagValue;
    staging: FlagValue;
    production: FlagValue;
}
/**
 * Map of flag name to definition.
 */
type FlagDefinitions<T extends string = string> = Record<T, FlagDefinition>;
/**
 * Resolved flags — all booleans.
 */
type ResolvedFlags<T extends string = string> = Record<T, boolean>;
/**
 * Allowlist configuration for tester-gated access.
 */
interface AllowlistConfig {
    /** Environment variable containing comma-separated emails */
    envVar?: string;
    /** Hardcoded fallback emails */
    fallback?: string[];
}
/**
 * Detect the current deployment stage from environment variables.
 */
declare function detectStage(): DeploymentStage;
/**
 * Create a type-safe feature flag system.
 *
 * @param definitions - Flag definitions per environment
 * @returns Feature flag accessor with resolve() and isEnabled()
 */
declare function createFeatureFlags<T extends string>(definitions: FlagDefinitions<T>): {
    /**
     * Resolve all flags for the current environment.
     * Call this once at startup or per-request for dynamic flags.
     */
    resolve(stage?: DeploymentStage): ResolvedFlags<T>;
    /**
     * Check if a single flag is enabled.
     */
    isEnabled(flag: T, stage?: DeploymentStage): boolean;
    /**
     * Get the flag definitions (for introspection/admin UI).
     */
    definitions: FlagDefinitions<T>;
};
/**
 * Build an allowlist from environment variable + fallback emails.
 *
 * @example
 * ```typescript
 * const testers = buildAllowlist({
 *   envVar: 'ADMIN_EMAILS',
 *   fallback: ['admin@example.com'],
 * })
 * if (testers.includes(userEmail)) { ... }
 * ```
 */
declare function buildAllowlist(config: AllowlistConfig): string[];
/**
 * Check if an email is in the allowlist (case-insensitive).
 */
declare function isAllowlisted(email: string, allowlist: string[]): boolean;

/**
 * Standalone Rate Limiter
 *
 * Framework-agnostic sliding window rate limiter that works with
 * any storage backend (Redis, memory, etc.). Apps provide a storage
 * adapter; this module handles the algorithm and types.
 *
 * @example
 * ```typescript
 * import {
 *   checkRateLimit,
 *   createMemoryRateLimitStore,
 *   CommonRateLimits,
 * } from '@digilogiclabs/platform-core'
 *
 * const store = createMemoryRateLimitStore()
 *
 * const result = await checkRateLimit('api-call', 'user:123', CommonRateLimits.apiGeneral, { store })
 * if (!result.allowed) {
 *   // Return 429 with result.retryAfterSeconds
 * }
 * ```
 */
/** Configuration for a rate limit rule */
interface RateLimitRule {
    /** Maximum requests allowed in the window */
    limit: number;
    /** Time window in seconds */
    windowSeconds: number;
    /** Different limit for authenticated users (optional) */
    authenticatedLimit?: number;
    /** Block duration in seconds when limit is exceeded (optional) */
    blockDurationSeconds?: number;
}
/** Result of a rate limit check */
interface RateLimitCheckResult {
    /** Whether the request is allowed */
    allowed: boolean;
    /** Remaining requests in the current window */
    remaining: number;
    /** Unix timestamp (ms) when the window resets */
    resetAt: number;
    /** Current request count in the window */
    current: number;
    /** The limit that was applied */
    limit: number;
    /** Seconds until retry is allowed (for 429 Retry-After header) */
    retryAfterSeconds: number;
}
/**
 * Storage backend for rate limiting.
 *
 * Implementations should support sorted-set-like semantics for
 * accurate sliding window rate limiting.
 */
interface RateLimitStore {
    /**
     * Add an entry to the sliding window and return the current count.
     * Should atomically: remove entries older than windowStart,
     * add the new entry, and return the total count.
     */
    increment(key: string, windowMs: number, now: number): Promise<{
        count: number;
    }>;
    /** Check if a key is blocked and return remaining TTL */
    isBlocked(key: string): Promise<{
        blocked: boolean;
        ttlMs: number;
    }>;
    /** Set a temporary block on a key */
    setBlock(key: string, durationSeconds: number): Promise<void>;
    /** Remove all entries for a key (for reset/testing) */
    reset(key: string): Promise<void>;
}
/** Options for checkRateLimit */
interface RateLimitOptions {
    /** Storage backend (defaults to in-memory if not provided) */
    store?: RateLimitStore;
    /** Whether the user is authenticated (uses authenticatedLimit if available) */
    isAuthenticated?: boolean;
    /** Logger for warnings/errors (optional) */
    logger?: {
        warn: (msg: string, meta?: Record<string, unknown>) => void;
        error: (msg: string, meta?: Record<string, unknown>) => void;
    };
}
/**
 * Common rate limit rules for typical operations.
 * Apps can extend with domain-specific presets.
 *
 * @example
 * ```typescript
 * const APP_LIMITS = {
 *   ...CommonRateLimits,
 *   serverCreate: { limit: 5, windowSeconds: 3600, blockDurationSeconds: 3600 },
 * }
 * ```
 */
declare const CommonRateLimits: {
    /** General API: 100/min, 200/min authenticated */
    readonly apiGeneral: {
        readonly limit: 100;
        readonly windowSeconds: 60;
        readonly authenticatedLimit: 200;
    };
    /** Admin actions: 100/min */
    readonly adminAction: {
        readonly limit: 100;
        readonly windowSeconds: 60;
    };
    /** Auth attempts: 10/15min with 30min block */
    readonly authAttempt: {
        readonly limit: 10;
        readonly windowSeconds: 900;
        readonly blockDurationSeconds: 1800;
    };
    /** AI/expensive requests: 20/hour, 50/hour authenticated */
    readonly aiRequest: {
        readonly limit: 20;
        readonly windowSeconds: 3600;
        readonly authenticatedLimit: 50;
    };
    /** Public form submissions: 5/hour with 1hr block */
    readonly publicForm: {
        readonly limit: 5;
        readonly windowSeconds: 3600;
        readonly blockDurationSeconds: 3600;
    };
    /** Checkout/billing: 10/hour with 1hr block */
    readonly checkout: {
        readonly limit: 10;
        readonly windowSeconds: 3600;
        readonly blockDurationSeconds: 3600;
    };
    /** Beta code validation: 5/min with 5min block (prevents brute force guessing) */
    readonly betaValidation: {
        readonly limit: 5;
        readonly windowSeconds: 60;
        readonly blockDurationSeconds: 300;
    };
};
/**
 * In-memory rate limit store for testing and graceful degradation.
 * Not suitable for multi-process or distributed environments.
 */
declare function createMemoryRateLimitStore(): RateLimitStore;
/**
 * Check rate limit for an operation.
 *
 * @param operation - Name of the operation (e.g., 'server-create', 'api-call')
 * @param identifier - Who is making the request (e.g., 'user:123', 'ip:1.2.3.4')
 * @param rule - Rate limit configuration
 * @param options - Storage, auth status, logger
 * @returns Rate limit check result
 */
declare function checkRateLimit(operation: string, identifier: string, rule: RateLimitRule, options?: RateLimitOptions): Promise<RateLimitCheckResult>;
/**
 * Get current rate limit status without incrementing the counter.
 */
declare function getRateLimitStatus(operation: string, identifier: string, rule: RateLimitRule, store?: RateLimitStore): Promise<RateLimitCheckResult | null>;
/**
 * Reset rate limit for an identifier (for admin/testing).
 */
declare function resetRateLimitForKey(operation: string, identifier: string, store?: RateLimitStore): Promise<void>;
/**
 * Build standard rate limit headers for HTTP responses.
 */
declare function buildRateLimitResponseHeaders(result: RateLimitCheckResult): Record<string, string>;
/**
 * Resolve a rate limit identifier from a request-like context.
 * Prefers user ID > email > IP for most accurate limiting.
 */
declare function resolveIdentifier(session: {
    user?: {
        id?: string;
        email?: string;
    };
} | null | undefined, clientIp?: string): {
    identifier: string;
    isAuthenticated: boolean;
};

/**
 * Audit Logging System
 *
 * Framework-agnostic audit logging for security-sensitive operations.
 * Provides structured audit events with actor, action, resource, and
 * outcome tracking. Apps provide their own persistence (Redis, DB, etc.)
 * via a simple callback; this module handles the event model and helpers.
 *
 * @example
 * ```typescript
 * import { createAuditLogger, StandardAuditActions } from '@digilogiclabs/platform-core'
 *
 * const audit = createAuditLogger({
 *   persist: async (record) => {
 *     await redis.setex(`audit:${record.id}`, 90 * 86400, JSON.stringify(record))
 *   },
 * })
 *
 * await audit.log({
 *   actor: { id: userId, email, type: 'user' },
 *   action: StandardAuditActions.LOGIN_SUCCESS,
 *   outcome: 'success',
 * })
 * ```
 */
/** Who performed the action */
interface OpsAuditActor {
    id: string;
    email?: string;
    type: "user" | "admin" | "system" | "api_key" | "anonymous";
    sessionId?: string;
}
/** What resource was affected */
interface OpsAuditResource {
    type: string;
    id: string;
    name?: string;
}
/** The audit event to log */
interface OpsAuditEvent {
    actor: OpsAuditActor;
    action: string;
    resource?: OpsAuditResource;
    outcome: "success" | "failure" | "blocked" | "pending";
    metadata?: Record<string, unknown>;
    reason?: string;
}
/** Complete audit record with context */
interface OpsAuditRecord extends OpsAuditEvent {
    id: string;
    timestamp: string;
    ip?: string;
    userAgent?: string;
    requestId?: string;
    duration?: number;
}
/** Options for creating an audit logger */
interface OpsAuditLoggerOptions {
    /**
     * Persist an audit record to storage (Redis, DB, etc.).
     * Called after console logging. Errors are caught and logged,
     * never thrown — audit failures must not break operations.
     */
    persist?: (record: OpsAuditRecord) => Promise<void>;
    /**
     * Console logger for structured output.
     * Defaults to console.log/console.warn.
     */
    logger?: {
        info: (msg: string, meta?: Record<string, unknown>) => void;
        warn: (msg: string, meta?: Record<string, unknown>) => void;
        error: (msg: string, meta?: Record<string, unknown>) => void;
    };
}
/** Request-like object for extracting IP, user agent, request ID */
interface AuditRequest {
    headers: {
        get(name: string): string | null;
    };
}
/**
 * Standard audit action constants.
 * Apps should extend with domain-specific actions:
 *
 * @example
 * ```typescript
 * const AppAuditActions = {
 *   ...StandardAuditActions,
 *   SERVER_CREATE: 'game.server.create',
 *   SERVER_DELETE: 'game.server.delete',
 * } as const
 * ```
 */
declare const StandardAuditActions: {
    readonly LOGIN_SUCCESS: "auth.login.success";
    readonly LOGIN_FAILURE: "auth.login.failure";
    readonly LOGOUT: "auth.logout";
    readonly SESSION_REFRESH: "auth.session.refresh";
    readonly PASSWORD_CHANGE: "auth.password.change";
    readonly PASSWORD_RESET: "auth.password.reset";
    readonly CHECKOUT_START: "billing.checkout.start";
    readonly CHECKOUT_COMPLETE: "billing.checkout.complete";
    readonly SUBSCRIPTION_CREATE: "billing.subscription.create";
    readonly SUBSCRIPTION_CANCEL: "billing.subscription.cancel";
    readonly SUBSCRIPTION_UPDATE: "billing.subscription.update";
    readonly PAYMENT_FAILED: "billing.payment.failed";
    readonly ADMIN_LOGIN: "admin.login";
    readonly ADMIN_USER_VIEW: "admin.user.view";
    readonly ADMIN_USER_UPDATE: "admin.user.update";
    readonly ADMIN_CONFIG_CHANGE: "admin.config.change";
    readonly RATE_LIMIT_EXCEEDED: "security.rate_limit.exceeded";
    readonly INVALID_INPUT: "security.input.invalid";
    readonly UNAUTHORIZED_ACCESS: "security.access.unauthorized";
    readonly OWNERSHIP_VIOLATION: "security.ownership.violation";
    readonly WEBHOOK_SIGNATURE_INVALID: "security.webhook.signature_invalid";
    readonly DATA_EXPORT: "data.export";
    readonly DATA_DELETE: "data.delete";
    readonly DATA_UPDATE: "data.update";
};
type StandardAuditActionType = (typeof StandardAuditActions)[keyof typeof StandardAuditActions];
/**
 * Extract client IP from request headers.
 * Checks common proxy headers in order of reliability.
 */
declare function extractAuditIp(request?: AuditRequest): string | undefined;
/**
 * Extract user agent from request.
 */
declare function extractAuditUserAgent(request?: AuditRequest): string | undefined;
/**
 * Extract or generate request ID.
 */
declare function extractAuditRequestId(request?: AuditRequest): string;
/**
 * Create an AuditActor from a session object.
 * Works with Auth.js/NextAuth session shape.
 */
declare function createAuditActor(session: {
    user?: {
        id?: string;
        email?: string | null;
    };
} | null | undefined): OpsAuditActor;
/**
 * Create an audit logger instance.
 *
 * @param options - Persistence callback and optional logger
 * @returns Audit logger with log() and createTimedAudit() methods
 */
declare function createAuditLogger(options?: OpsAuditLoggerOptions): {
    log: (event: OpsAuditEvent, request?: AuditRequest) => Promise<OpsAuditRecord>;
    createTimedAudit: (event: Omit<OpsAuditEvent, "outcome">, request?: AuditRequest) => {
        success: (metadata?: Record<string, unknown>) => Promise<OpsAuditRecord>;
        failure: (reason: string, metadata?: Record<string, unknown>) => Promise<OpsAuditRecord>;
        blocked: (reason: string, metadata?: Record<string, unknown>) => Promise<OpsAuditRecord>;
    };
};

/**
 * Beta Client Utilities
 *
 * Shared client-side helpers for beta access management.
 * These run in the browser and talk to your app's beta API endpoints.
 *
 * Standardizes the pattern used across DLL, WIAN, and future apps:
 * - Fetch beta settings from API
 * - Validate invite codes
 * - Store/retrieve beta code across OAuth redirect flows (sessionStorage)
 *
 * @example
 * ```typescript
 * import {
 *   fetchBetaSettings,
 *   validateBetaCode,
 *   storeBetaCode,
 *   getStoredBetaCode,
 *   clearStoredBetaCode,
 * } from '@digilogiclabs/platform-core/auth';
 *
 * // On sign-in page mount
 * const settings = await fetchBetaSettings();
 * if (settings.requireInviteCode) {
 *   const result = await validateBetaCode(userInput);
 *   if (result.valid) {
 *     storeBetaCode(userInput); // Survives OAuth redirect
 *     // Proceed with sign-in
 *   }
 * }
 * ```
 */

interface BetaClientConfig {
    /** Base URL for API calls (default: '' for same-origin) */
    baseUrl?: string;
    /** API endpoint for settings (default: '/api/beta-settings') */
    settingsEndpoint?: string;
    /** API endpoint for validation (default: '/api/validate-beta-code') */
    validateEndpoint?: string;
    /** sessionStorage key for storing beta code (default: 'beta_code') */
    storageKey?: string;
    /** Default settings to use when fetch fails */
    failSafeDefaults?: Partial<BetaSettings>;
}
/**
 * Create a configured beta client with app-specific settings.
 *
 * @example
 * ```typescript
 * // DLL app
 * const betaClient = createBetaClient({
 *   storageKey: 'dll_beta_code',
 *   validateEndpoint: '/api/validate-beta-code',
 * });
 *
 * // WIAN app
 * const betaClient = createBetaClient({
 *   storageKey: 'wian_beta_code',
 *   validateEndpoint: '/api/validate-invite-code',
 * });
 * ```
 */
declare function createBetaClient(config?: BetaClientConfig): {
    fetchSettings: () => Promise<BetaSettings>;
    validateCode: (code: string) => Promise<BetaValidationResult>;
    storeCode: (code: string) => void;
    getStoredCode: () => string | null;
    clearStoredCode: () => void;
};
/**
 * Fetch beta settings from the server.
 * Returns fail-safe defaults if the fetch fails.
 */
declare function fetchBetaSettings(config?: BetaClientConfig): Promise<BetaSettings>;
/**
 * Validate a beta invite code against the server.
 * Handles rate limiting (429) gracefully.
 */
declare function validateBetaCode(code: string, config?: BetaClientConfig): Promise<BetaValidationResult>;
/**
 * Store a validated beta code in sessionStorage.
 * Used to pass the code through OAuth redirect flows.
 */
declare function storeBetaCode(code: string, config?: BetaClientConfig): void;
/**
 * Retrieve stored beta code from sessionStorage.
 */
declare function getStoredBetaCode(config?: BetaClientConfig): string | null;
/**
 * Clear stored beta code from sessionStorage.
 */
declare function clearStoredBetaCode(config?: BetaClientConfig): void;

/**
 * Environment Variable Helpers
 *
 * Type-safe, fail-fast utilities for reading environment variables.
 * Every app needs these — extracted from DLL, WIAN, and OSS patterns.
 *
 * @example
 * ```typescript
 * import { getRequiredEnv, getOptionalEnv, getBoolEnv, validateEnvVars } from '@digilogiclabs/platform-core'
 *
 * const config = {
 *   stripe: { secretKey: getRequiredEnv('STRIPE_SECRET_KEY') },
 *   redis: { url: getOptionalEnv('REDIS_URL', '') },
 *   features: { debug: getBoolEnv('DEBUG', false) },
 * }
 *
 * // Validate at startup
 * validateEnvVars({
 *   required: ['STRIPE_SECRET_KEY', 'DATABASE_URL'],
 *   requireOneOf: [['DATABASE_URL', 'SUPABASE_URL']], // at least one
 *   validators: {
 *     DATABASE_URL: (v) => v.startsWith('postgres') || 'must start with postgres://',
 *     ADMIN_SECRET: (v) => v.length >= 32 || 'must be at least 32 characters',
 *   },
 * })
 * ```
 */
/**
 * Get a required environment variable.
 * Throws immediately if not set — fail-fast at startup.
 */
declare function getRequiredEnv(key: string): string;
/**
 * Get an optional environment variable with a default value.
 */
declare function getOptionalEnv(key: string, defaultValue: string): string;
/**
 * Get a boolean environment variable.
 * Treats "true" and "1" as true, everything else as false.
 */
declare function getBoolEnv(key: string, defaultValue?: boolean): boolean;
/**
 * Get a numeric environment variable with a default.
 */
declare function getIntEnv(key: string, defaultValue: number): number;
/**
 * Configuration for environment validation.
 */
interface EnvValidationConfig {
    /** Variables that must be set (non-empty) */
    required?: string[];
    /** Groups where at least one must be set (e.g., DATABASE_URL or SUPABASE_URL) */
    requireOneOf?: string[][];
    /** Custom validators — return true or an error message */
    validators?: Record<string, (value: string) => true | string>;
}
/**
 * Validation result with categorized errors.
 */
interface EnvValidationResult {
    valid: boolean;
    missing: string[];
    invalid: {
        key: string;
        reason: string;
    }[];
    missingOneOf: string[][];
}
/**
 * Validate environment variables against a configuration.
 *
 * @throws Error with details about all missing/invalid variables
 */
declare function validateEnvVars(config: EnvValidationConfig): void;
/**
 * Check environment variables without throwing.
 * Returns a result object for custom error handling.
 */
declare function checkEnvVars(config: EnvValidationConfig): EnvValidationResult;
/**
 * Get a redacted config summary for debugging.
 * Shows which variables are configured without exposing values.
 */
declare function getEnvSummary(keys: string[]): Record<string, boolean>;

export { EmailSchema as $, ApiError as A, getEndSessionEndpoint as B, CommonApiErrors as C, refreshKeycloakToken as D, type EnvValidationConfig as E, type KeycloakCallbacksConfig as F, type KeycloakJwtFields as G, type AuthCookiesConfig as H, buildAuthCookies as I, type RedirectCallbackConfig as J, type KeycloakConfig as K, buildRedirectCallback as L, buildKeycloakCallbacks as M, type AuthMethod as N, type RouteAuditConfig as O, type RateLimitPreset as P, type ApiSecurityConfig as Q, type RateLimitStore as R, StandardRateLimitPresets as S, type TokenRefreshResult as T, type SecuritySession as U, type ApiSecurityContext as V, resolveRateLimitIdentifier as W, extractClientIp as X, buildRateLimitHeaders as Y, buildErrorBody as Z, WrapperPresets as _, type RateLimitRule as a, type BetaTester as a$, PasswordSchema as a0, SlugSchema as a1, PhoneSchema as a2, PersonNameSchema as a3, createSafeTextSchema as a4, PaginationSchema as a5, DateRangeSchema as a6, SearchQuerySchema as a7, LoginSchema as a8, SignupSchema as a9, type OpsAuditEvent as aA, type OpsAuditRecord as aB, type OpsAuditLoggerOptions as aC, type AuditRequest as aD, StandardAuditActions as aE, type StandardAuditActionType as aF, extractAuditIp as aG, extractAuditUserAgent as aH, extractAuditRequestId as aI, createAuditActor as aJ, createAuditLogger as aK, type BetaClientConfig as aL, createBetaClient as aM, fetchBetaSettings as aN, validateBetaCode as aO, storeBetaCode as aP, getStoredBetaCode as aQ, clearStoredBetaCode as aR, type IBeta as aS, type BetaConfig as aT, type BetaSettings as aU, type UpdateBetaSettingsOptions as aV, type CreateBetaCodesOptions as aW, type BetaInviteCode as aX, type ListBetaCodesOptions as aY, type BetaValidationResult as aZ, type BetaConsumeResult as a_, type EmailInput as aa, type PaginationInput as ab, type DateRangeInput as ac, type SearchQueryInput as ad, type LoginInput as ae, type SignupInput as af, type DeploymentStage as ag, type FlagValue as ah, type FlagDefinition as ai, type FlagDefinitions as aj, type ResolvedFlags as ak, type AllowlistConfig as al, detectStage as am, createFeatureFlags as an, buildAllowlist as ao, isAllowlisted as ap, type RateLimitCheckResult as aq, CommonRateLimits as ar, createMemoryRateLimitStore as as, checkRateLimit as at, getRateLimitStatus as au, resetRateLimitForKey as av, buildRateLimitResponseHeaders as aw, resolveIdentifier as ax, type OpsAuditActor as ay, type OpsAuditResource as az, type RateLimitOptions as b, type BetaStats as b0, type BetaCodeUsageReport as b1, MemoryBeta as b2, generateBetaCode as b3, normalizeBetaCode as b4, generateBetaId as b5, type BetaCodeStatus as b6, PG_ERROR_MAP as b7, classifyError as c, ApiErrorCode as d, buildPagination as e, type ApiErrorCodeType as f, type ApiSuccessResponse as g, type ApiPaginatedResponse as h, isApiError as i, getRequiredEnv as j, getOptionalEnv as k, getBoolEnv as l, getIntEnv as m, checkEnvVars as n, getEnvSummary as o, type EnvValidationResult as p, type KeycloakTokenSet as q, KEYCLOAK_DEFAULT_ROLES as r, parseKeycloakRoles as s, hasRole as t, hasAnyRole as u, validateEnvVars as v, hasAllRoles as w, isTokenExpired as x, buildTokenRefreshParams as y, getTokenEndpoint as z };
