import { ComponentType, ReactNode } from 'react';
import * as v from 'valibot';
import { InitOptions, TFunction } from 'i18next';
import { FieldValues } from 'react-hook-form';
import { useTranslation } from 'react-i18next';

/**
 * @fileoverview AI Constants
 * @description Provider IDs, model lists, roles, defaults for AI feature.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */
/** Supported AI providers */
declare const AI_PROVIDERS: {
    readonly ANTHROPIC: "anthropic";
    readonly OPENAI: "openai";
    readonly GOOGLE: "google";
};
/** Message roles */
declare const AI_ROLES: {
    readonly USER: "user";
    readonly ASSISTANT: "assistant";
    readonly SYSTEM: "system";
};
/** Default models per provider */
declare const AI_MODELS: {
    readonly anthropic: {
        readonly default: "claude-sonnet-4-6";
        readonly models: readonly ["claude-sonnet-4-6", "claude-sonnet-4-20250514", "claude-haiku-4-5-20251001", "claude-opus-4-6", "claude-opus-4-20250514"];
    };
    readonly openai: {
        readonly default: "gpt-4o";
        readonly models: readonly ["gpt-4o", "gpt-4o-mini", "gpt-4.1", "gpt-4.1-mini", "o3-mini"];
    };
    readonly google: {
        readonly default: "gemini-2.0-flash";
        readonly models: readonly ["gemini-2.0-flash", "gemini-2.5-pro", "gemini-2.5-flash"];
    };
};
/** Default AI configuration */
declare const DEFAULT_AI_CONFIG: {
    readonly maxTokens: 4096;
    readonly temperature: 0.7;
    readonly stream: true;
};
/** AI error codes */
declare const AI_ERROR_CODES: {
    readonly UNKNOWN: "unknown";
    readonly UNAUTHENTICATED: "unauthenticated";
    readonly INVALID_API_KEY: "invalid_api_key";
    readonly RATE_LIMIT_EXCEEDED: "rate_limit_exceeded";
    readonly PROVIDER_ERROR: "provider_error";
    readonly TOKEN_LIMIT_EXCEEDED: "token_limit_exceeded";
    readonly STREAM_INTERRUPTED: "stream_interrupted";
};
/** AI model tiers - SSOT for tier-based model resolution */
declare const AI_TIERS: {
    readonly FAST: {
        readonly id: "fast";
        readonly defaultModel: "claude-haiku-4-5-20251001";
    };
    readonly STANDARD: {
        readonly id: "standard";
        readonly defaultModel: "claude-sonnet-4-6";
    };
    readonly PREMIUM: {
        readonly id: "premium";
        readonly defaultModel: "claude-opus-4-6";
    };
};
/** AI tier identifier derived from AI_TIERS constant. */
type AITierId = (typeof AI_TIERS)[keyof typeof AI_TIERS]['id'];
/** Default markup multiplier (provider cost x 4 = billed cost) */
declare const DEFAULT_AI_MARKUP = 4;
/**
 * Token pricing per model (USD per 1M tokens).
 * SSOT - imported by both client (cost display) and server (cost recording).
 */
declare const AI_TOKEN_PRICING: Record<string, {
    promptPer1M: number;
    completionPer1M: number;
    currency: 'usd';
}>;

/**
 * @fileoverview AI Schemas
 * @description Valibot schemas for AI request/response validation.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */

/** Schema for a single AI message */
declare const AIMessageSchema: v.ObjectSchema<{
    readonly role: v.PicklistSchema<["user", "assistant", "system"], undefined>;
    readonly content: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly createdAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/** Schema for an AI tool definition */
declare const AIToolDefinitionSchema: v.ObjectSchema<{
    readonly description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    readonly parameters: v.ObjectSchema<{
        readonly type: v.LiteralSchema<"object", undefined>;
        readonly properties: v.RecordSchema<v.StringSchema<undefined>, v.GenericSchema<any>, undefined>;
        readonly required: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    }, undefined>;
}, undefined>;
/** Schema for a tool call result */
declare const AIToolCallSchema: v.ObjectSchema<{
    readonly id: v.StringSchema<undefined>;
    readonly name: v.StringSchema<undefined>;
    readonly args: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
}, undefined>;
/** Schema for AI chat request (client → server) */
declare const AIChatRequestSchema: v.ObjectSchema<{
    readonly messages: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
        readonly role: v.PicklistSchema<["user", "assistant", "system"], undefined>;
        readonly content: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly createdAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>, undefined>, v.MinLengthAction<{
        role: "user" | "assistant" | "system";
        content: string;
        id?: string | undefined;
        createdAt?: string | undefined;
    }[], 1, undefined>]>;
    readonly provider: v.OptionalSchema<v.PicklistSchema<["anthropic", "openai", "google"], undefined>, undefined>;
    readonly model: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly maxTokens: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly temperature: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>, undefined>;
    readonly systemPrompt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly stream: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly tools: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
        readonly description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        readonly parameters: v.ObjectSchema<{
            readonly type: v.LiteralSchema<"object", undefined>;
            readonly properties: v.RecordSchema<v.StringSchema<undefined>, v.GenericSchema<any>, undefined>;
            readonly required: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        }, undefined>;
    }, undefined>, undefined>, undefined>;
}, undefined>;
/** Schema for AI token usage */
declare const AIUsageSchema: v.ObjectSchema<{
    readonly promptTokens: v.NumberSchema<undefined>;
    readonly completionTokens: v.NumberSchema<undefined>;
    readonly totalTokens: v.NumberSchema<undefined>;
}, undefined>;
/** Schema for AI chat response (server → client, non-streaming) */
declare const AIChatResponseSchema: v.ObjectSchema<{
    readonly message: v.ObjectSchema<{
        readonly role: v.PicklistSchema<["user", "assistant", "system"], undefined>;
        readonly content: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly createdAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>;
    readonly usage: v.OptionalSchema<v.ObjectSchema<{
        readonly promptTokens: v.NumberSchema<undefined>;
        readonly completionTokens: v.NumberSchema<undefined>;
        readonly totalTokens: v.NumberSchema<undefined>;
    }, undefined>, undefined>;
    readonly finishReason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly toolCalls: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
        readonly id: v.StringSchema<undefined>;
        readonly name: v.StringSchema<undefined>;
        readonly args: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    }, undefined>, undefined>, undefined>;
}, undefined>;
/** Schema for AI provider configuration (consumer's _shared/aiConfig.ts) */
declare const AIProviderConfigSchema: v.ObjectSchema<{
    readonly provider: v.PicklistSchema<["anthropic", "openai", "google"], undefined>;
    readonly model: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly maxTokens: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly temperature: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>, undefined>;
    readonly systemPrompt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/** A single message in an AI chat conversation. */
type AIMessage = v.InferOutput<typeof AIMessageSchema>;
/** Request payload for an AI chat completion. */
type AIChatRequest = v.InferOutput<typeof AIChatRequestSchema>;
/** Token usage statistics for an AI completion. */
type AIUsage = v.InferOutput<typeof AIUsageSchema>;
/** Response payload from an AI chat completion. */
type AIChatResponse = v.InferOutput<typeof AIChatResponseSchema>;
/** Configuration for an AI provider backend. */
type AIProviderConfig = v.InferOutput<typeof AIProviderConfigSchema>;
declare function validateAIChatRequest(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly messages: v.SchemaWithPipe<readonly [v.ArraySchema<v.ObjectSchema<{
        readonly role: v.PicklistSchema<["user", "assistant", "system"], undefined>;
        readonly content: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly createdAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>, undefined>, v.MinLengthAction<{
        role: "user" | "assistant" | "system";
        content: string;
        id?: string | undefined;
        createdAt?: string | undefined;
    }[], 1, undefined>]>;
    readonly provider: v.OptionalSchema<v.PicklistSchema<["anthropic", "openai", "google"], undefined>, undefined>;
    readonly model: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly maxTokens: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly temperature: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>, v.MaxValueAction<number, 2, undefined>]>, undefined>;
    readonly systemPrompt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly stream: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly tools: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
        readonly description: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        readonly parameters: v.ObjectSchema<{
            readonly type: v.LiteralSchema<"object", undefined>;
            readonly properties: v.RecordSchema<v.StringSchema<undefined>, v.GenericSchema<any>, undefined>;
            readonly required: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        }, undefined>;
    }, undefined>, undefined>, undefined>;
}, undefined>>;
declare function validateAIChatResponse(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly message: v.ObjectSchema<{
        readonly role: v.PicklistSchema<["user", "assistant", "system"], undefined>;
        readonly content: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        readonly id: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly createdAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>;
    readonly usage: v.OptionalSchema<v.ObjectSchema<{
        readonly promptTokens: v.NumberSchema<undefined>;
        readonly completionTokens: v.NumberSchema<undefined>;
        readonly totalTokens: v.NumberSchema<undefined>;
    }, undefined>, undefined>;
    readonly finishReason: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly toolCalls: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
        readonly id: v.StringSchema<undefined>;
        readonly name: v.StringSchema<undefined>;
        readonly args: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    }, undefined>, undefined>, undefined>;
}, undefined>>;

/** AI provider type */
type AIProvider = (typeof AI_PROVIDERS)[keyof typeof AI_PROVIDERS];
/** AI error code type (derived from AI_ERROR_CODES constant) */
type AIErrorCode = (typeof AI_ERROR_CODES)[keyof typeof AI_ERROR_CODES];
/** Configuration for AI feature (consumer-facing) */
interface AIConfig {
    provider: AIProvider;
    model?: string;
    maxTokens?: number;
    temperature?: number;
    systemPrompt?: string;
}
/** Per-model token pricing */
interface AIModelPricing {
    /** Cost per 1M input tokens in USD */
    promptPer1M: number;
    /** Cost per 1M output tokens in USD */
    completionPer1M: number;
    /** Currency code */
    currency: 'usd';
}
/** Cost calculation result */
interface AICostResult {
    /** Raw provider cost in USD (server-side only, never expose to end users) */
    providerCost: number;
    /** Marked-up cost for consumer billing (what users owe) */
    billedCost: number;
    /** Markup multiplier applied */
    markup: number;
    /** Breakdown */
    breakdown: {
        promptTokens: number;
        completionTokens: number;
        promptCost: number;
        completionCost: number;
    };
}
/** Consumer-facing cost configuration */
interface AICostConfig {
    /** Markup multiplier for rebilling (provider cost x markup = billed cost) */
    markup: number;
    /** Monthly token budget per user (0 = unlimited) */
    monthlyBudgetTokens: number;
    /** Whether to show cost to end users (false = admin only) */
    showCostToUsers: boolean;
    /** Currency for display */
    displayCurrency: string;
}
/** Server-side cost record (written per AI request) */
interface AICostRecord {
    userId: string;
    model: string;
    provider: string;
    usage: AIUsage;
    providerCost: number;
    billedCost: number;
    markup: number;
    timestamp: string;
    requestId: string;
}
/** Real-time cost event for billing integration */
interface AICostEvent {
    type: 'cost_update';
    requestId: string;
    cost: AICostResult;
    cumulative: AICostResult;
}
/** JSON Schema property definition for AI tool parameters */
interface AIToolParameter {
    /** JSON Schema type */
    type: 'string' | 'number' | 'boolean' | 'array' | 'object';
    /** Parameter description (sent to the model) */
    description?: string;
    /** Enum constraint */
    enum?: string[];
    /** Array items schema */
    items?: AIToolParameter;
    /** Object properties */
    properties?: Record<string, AIToolParameter>;
    /** Required property names (for object type) */
    required?: string[];
}
/** AI tool definition - JSON Schema based, provider-agnostic */
interface AIToolDefinition {
    /** Tool description (sent to the model) */
    description: string;
    /** Tool parameters as JSON Schema object */
    parameters: {
        type: 'object';
        properties: Record<string, AIToolParameter>;
        required?: string[];
    };
}
/** Result of a tool call made by the model */
interface AIToolCall {
    /** Tool call ID (from provider) */
    id: string;
    /** Tool name */
    name: string;
    /** Parsed arguments */
    args: Record<string, unknown>;
}
/** AI API surface - returned by useAIChat, degraded when @donotdev/ai not installed */
interface AIAPI {
    /** Conversation messages */
    messages: AIMessage[];
    /** Send a message */
    append: (content: string) => void;
    /** Stop current stream */
    stop: () => void;
    /** Whether a response is streaming */
    isLoading: boolean;
    /** Current error */
    error: Error | undefined;
    /** Clear conversation */
    clearMessages: () => void;
    /** Whether AI is available (auth + consent) */
    isAvailable: boolean;
    /** Current input value (controlled) */
    input: string;
    /** Set input value */
    setInput: (value: string) => void;
    /** Submit the current input */
    handleSubmit: (e?: any) => void;
    /** Cost tracking (billed cost only - provider cost is server-side only) */
    cost: {
        lastCost: AICostResult | null;
        sessionCost: AICostResult;
        formattedBilledCost: string;
    };
    /** Tool calls from the latest assistant response */
    toolCalls: AIToolCall[];
}
/** Rate limit configuration for AI handler */
interface AIRateLimitConfig {
    /** Maximum requests per window */
    maxRequests: number;
    /** Window duration in milliseconds */
    windowMs: number;
}
/** AI route configuration (server-side) */
interface AIRouteConfig {
    /** AI provider */
    provider: AIProvider;
    /** Model ID */
    model?: string;
    /** Max output tokens */
    maxTokens?: number;
    /** Temperature */
    temperature?: number;
    /** System prompt */
    systemPrompt?: string;
    /** Cost configuration */
    cost?: AICostConfig;
    /** Rate limit configuration */
    rateLimitConfig?: AIRateLimitConfig;
    /** Tool definitions available to the model */
    tools?: Record<string, AIToolDefinition>;
}

/**
 * @fileoverview Partners Constants
 * @description Constants for partners domain. Defines partner icon mappings and partner-related constants.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Partner icon constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const PARTNER_ICONS: {
    readonly apple: "apple";
    readonly discord: "discord";
    readonly emailLink: "emailLink";
    readonly facebook: "facebook";
    readonly github: "github";
    readonly google: "google";
    readonly linkedin: "linkedin";
    readonly microsoft: "microsoft";
    readonly password: "password";
    readonly reddit: "reddit";
    readonly spotify: "spotify";
    readonly twitch: "twitch";
    readonly twitter: "twitter";
    readonly yahoo: "yahoo";
    readonly notion: "notion";
    readonly slack: "slack";
    readonly medium: "medium";
    readonly mastodon: "mastodon";
    readonly youtube: "youtube";
};
/**
 * Partner icon ID type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PartnerIconId = keyof typeof PARTNER_ICONS;

/**
 * @fileoverview Schema Definition for All Authentication and OAuth Partners
 * @description Single source of truth for all auth and OAuth configurations. Defines Valibot schemas for partner configurations, authentication partners, and OAuth partners.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Partner type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PartnerType = 'auth' | 'oauth' | 'both';
declare const authPartnerSchema: v.ObjectSchema<{
    readonly type: v.PicklistSchema<["auth", "both"], undefined>;
    readonly scopes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    readonly firebaseProviderId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly name: v.StringSchema<undefined>;
    readonly color: v.StringSchema<undefined>;
    readonly icon: v.StringSchema<undefined>;
    readonly customParameters: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
    readonly button: v.ObjectSchema<{
        readonly backgroundColor: v.StringSchema<undefined>;
        readonly textColor: v.StringSchema<undefined>;
        readonly borderColor: v.StringSchema<undefined>;
        readonly hoverBackgroundColor: v.StringSchema<undefined>;
        readonly focusOutlineColor: v.StringSchema<undefined>;
        readonly fontWeight: v.OptionalSchema<v.StringSchema<undefined>, "500">;
        readonly textKey: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>;
}, undefined>;
/**
 * Authentication partners configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const AUTH_PARTNERS: {
    readonly apple: {
        readonly name: "Apple";
        readonly color: "#000000";
        readonly icon: "apple";
        readonly type: "both";
        readonly scopes: readonly ["email", "name"];
        readonly firebaseProviderId: "apple.com";
        readonly customParameters: {
            readonly prompt: "login";
        };
        readonly button: {
            readonly backgroundColor: "#000000";
            readonly textColor: "#ffffff";
            readonly borderColor: "#000000";
            readonly hoverBackgroundColor: "#1a1a1a";
            readonly focusOutlineColor: "#333333";
            readonly fontWeight: "500";
            readonly textKey: "buttons.apple";
        };
    };
    readonly discord: {
        readonly name: "Discord";
        readonly color: "#5865F2";
        readonly icon: "discord";
        readonly type: "both";
        readonly scopes: readonly ["identify", "email"];
        readonly firebaseProviderId: "discord.com";
        readonly customParameters: {
            readonly prompt: "consent";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.discord";
        };
    };
    readonly emailLink: {
        readonly name: "Email Link";
        readonly color: "#10B981";
        readonly icon: "emailLink";
        readonly type: "auth";
        readonly scopes: readonly [];
        readonly firebaseProviderId: "emailLink";
        readonly customParameters: {};
        readonly button: {
            readonly backgroundColor: "#10B981";
            readonly textColor: "#ffffff";
            readonly borderColor: "#10B981";
            readonly hoverBackgroundColor: "#059669";
            readonly focusOutlineColor: "#059669";
            readonly fontWeight: "500";
            readonly textKey: "buttons.emailLink";
        };
    };
    readonly facebook: {
        readonly name: "Facebook";
        readonly color: "#1877F2";
        readonly icon: "facebook";
        readonly type: "both";
        readonly scopes: readonly ["email", "public_profile"];
        readonly firebaseProviderId: "facebook.com";
        readonly customParameters: {
            readonly auth_type: "reauthenticate";
        };
        readonly button: {
            readonly backgroundColor: "#1877F2";
            readonly textColor: "#ffffff";
            readonly borderColor: "#1877F2";
            readonly hoverBackgroundColor: "#166FE5";
            readonly focusOutlineColor: "#166FE5";
            readonly fontWeight: "600";
            readonly textKey: "buttons.facebook";
        };
    };
    readonly github: {
        readonly name: "GitHub";
        readonly color: "#24292E";
        readonly icon: "github";
        readonly type: "both";
        readonly scopes: readonly ["read:user", "user:email"];
        readonly firebaseProviderId: "github.com";
        readonly customParameters: {
            readonly allow_signup: "true";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.github";
        };
    };
    readonly google: {
        readonly name: "Google";
        readonly color: "#4285F4";
        readonly icon: "google";
        readonly type: "both";
        readonly scopes: readonly ["email", "profile"];
        readonly firebaseProviderId: "google.com";
        readonly customParameters: {
            readonly prompt: "select_account";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.google";
        };
    };
    readonly linkedin: {
        readonly name: "LinkedIn";
        readonly color: "#0077B5";
        readonly icon: "linkedin";
        readonly type: "both";
        readonly scopes: readonly ["r_liteprofile", "r_emailaddress"];
        readonly firebaseProviderId: "linkedin.com";
        readonly customParameters: {
            readonly prompt: "consent";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.linkedin";
        };
    };
    readonly microsoft: {
        readonly name: "Microsoft";
        readonly color: "#00A4EF";
        readonly icon: "microsoft";
        readonly type: "both";
        readonly scopes: readonly ["openid", "email", "profile"];
        readonly firebaseProviderId: "microsoft.com";
        readonly customParameters: {
            readonly prompt: "select_account";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.microsoft";
        };
    };
    readonly password: {
        readonly name: "Email & Password";
        readonly color: "#6B7280";
        readonly icon: "password";
        readonly type: "auth";
        readonly scopes: readonly [];
        readonly firebaseProviderId: "password";
        readonly customParameters: {};
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#374151";
            readonly borderColor: "#D1D5DB";
            readonly hoverBackgroundColor: "#F9FAFB";
            readonly focusOutlineColor: "#3B82F6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.password";
        };
    };
    readonly reddit: {
        readonly name: "Reddit";
        readonly color: "#FF4500";
        readonly icon: "reddit";
        readonly type: "both";
        readonly scopes: readonly ["identity"];
        readonly firebaseProviderId: "reddit.com";
        readonly customParameters: {
            readonly duration: "permanent";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.reddit";
        };
    };
    readonly spotify: {
        readonly name: "Spotify";
        readonly color: "#1DB954";
        readonly icon: "spotify";
        readonly type: "both";
        readonly scopes: readonly ["user-read-email", "user-read-private"];
        readonly firebaseProviderId: "spotify.com";
        readonly customParameters: {
            readonly show_dialog: "true";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.spotify";
        };
    };
    readonly twitch: {
        readonly name: "Twitch";
        readonly color: "#9146FF";
        readonly icon: "twitch";
        readonly type: "both";
        readonly scopes: readonly ["user:read:email"];
        readonly firebaseProviderId: "twitch.tv";
        readonly customParameters: {
            readonly force_verify: "true";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.twitch";
        };
    };
    readonly twitter: {
        readonly name: "X";
        readonly color: "#000000";
        readonly icon: "twitter";
        readonly type: "both";
        readonly scopes: readonly [];
        readonly firebaseProviderId: "twitter.com";
        readonly customParameters: {
            readonly force_login: "true";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.twitter";
        };
    };
    readonly yahoo: {
        readonly name: "Yahoo";
        readonly color: "#5F01D1";
        readonly icon: "yahoo";
        readonly type: "both";
        readonly scopes: readonly ["openid", "email", "profile"];
        readonly firebaseProviderId: "yahoo.com";
        readonly customParameters: {
            readonly prompt: "select_account";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
            readonly textKey: "buttons.yahoo";
        };
    };
};
/**
 * OAuth partners configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const OAUTH_PARTNERS: {
    readonly google: {
        readonly name: "Google";
        readonly color: "#4285F4";
        readonly icon: "google";
        readonly type: "both";
        readonly scopes: {
            readonly authentication: readonly ["openid", "profile", "email"];
            readonly 'api-access': readonly ["https://www.googleapis.com/auth/drive.readonly", "https://www.googleapis.com/auth/userinfo.profile", "https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/gmail.readonly"];
        };
        readonly endpoints: {
            readonly authUrl: "https://accounts.google.com/o/oauth2/v2/auth";
            readonly tokenUrl: "https://oauth2.googleapis.com/token";
            readonly profileUrl: "https://www.googleapis.com/oauth2/v3/userinfo";
            readonly revokeUrl: "https://oauth2.googleapis.com/revoke";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly github: {
        readonly name: "GitHub";
        readonly color: "#24292E";
        readonly icon: "github";
        readonly type: "both";
        readonly scopes: {
            readonly authentication: readonly ["read:user", "user:email"];
            readonly 'api-access': readonly ["repo", "user", "read:org", "gist", "notifications"];
        };
        readonly endpoints: {
            readonly authUrl: "https://github.com/login/oauth/authorize";
            readonly tokenUrl: "https://github.com/login/oauth/access_token";
            readonly profileUrl: "https://api.github.com/user";
            readonly revokeUrl: "https://api.github.com/applications/CLIENT_ID/token";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly discord: {
        readonly name: "Discord";
        readonly color: "#5865F2";
        readonly icon: "discord";
        readonly type: "both";
        readonly scopes: {
            readonly authentication: readonly ["identify", "email"];
            readonly 'api-access': readonly ["guilds", "guilds.members.read", "bot", "messages.read"];
        };
        readonly endpoints: {
            readonly authUrl: "https://discord.com/api/oauth2/authorize";
            readonly tokenUrl: "https://discord.com/api/oauth2/token";
            readonly profileUrl: "https://discord.com/api/users/@me";
            readonly revokeUrl: "https://discord.com/api/oauth2/token/revoke";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly spotify: {
        readonly name: "Spotify";
        readonly color: "#1DB954";
        readonly icon: "spotify";
        readonly type: "both";
        readonly scopes: {
            readonly authentication: readonly ["user-read-email", "user-read-private"];
            readonly 'api-access': readonly ["user-read-playback-state", "user-modify-playback-state", "user-read-currently-playing", "playlist-read-private", "playlist-modify-public", "user-library-read"];
        };
        readonly endpoints: {
            readonly authUrl: "https://accounts.spotify.com/authorize";
            readonly tokenUrl: "https://accounts.spotify.com/api/token";
            readonly profileUrl: "https://api.spotify.com/v1/me";
            readonly revokeUrl: "https://accounts.spotify.com/api/token";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly twitch: {
        readonly name: "Twitch";
        readonly color: "#9146FF";
        readonly icon: "twitch";
        readonly type: "both";
        readonly scopes: {
            readonly authentication: readonly ["user:read:email"];
            readonly 'api-access': readonly ["channel:read:subscriptions", "bits:read", "channel:manage:broadcast", "channel:read:stream_key", "user:read:follows"];
        };
        readonly endpoints: {
            readonly authUrl: "https://id.twitch.tv/oauth2/authorize";
            readonly tokenUrl: "https://id.twitch.tv/oauth2/token";
            readonly profileUrl: "https://api.twitch.tv/helix/users";
            readonly revokeUrl: "https://id.twitch.tv/oauth2/revoke";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly reddit: {
        readonly name: "Reddit";
        readonly color: "#FF4500";
        readonly icon: "reddit";
        readonly type: "both";
        readonly scopes: {
            readonly authentication: readonly ["identity"];
            readonly 'api-access': readonly ["read", "submit", "vote", "mysubreddits", "subscribe"];
        };
        readonly endpoints: {
            readonly authUrl: "https://www.reddit.com/api/v1/authorize";
            readonly tokenUrl: "https://www.reddit.com/api/v1/access_token";
            readonly profileUrl: "https://oauth.reddit.com/api/v1/me";
            readonly revokeUrl: "https://www.reddit.com/api/v1/revoke_token";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly linkedin: {
        readonly name: "LinkedIn";
        readonly color: "#0077B5";
        readonly icon: "linkedin";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["r_liteprofile", "r_emailaddress", "w_member_social", "r_organization_social"];
        };
        readonly endpoints: {
            readonly authUrl: "https://www.linkedin.com/oauth/v2/authorization";
            readonly tokenUrl: "https://www.linkedin.com/oauth/v2/accessToken";
            readonly profileUrl: "https://api.linkedin.com/v2/me";
            readonly revokeUrl: "https://www.linkedin.com/oauth/v2/revoke";
        };
        readonly capabilities: {
            readonly pkce: false;
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly slack: {
        readonly name: "Slack";
        readonly color: "#E01E5A";
        readonly icon: "slack";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["channels:read", "chat:write", "users:read", "files:read", "im:read"];
        };
        readonly endpoints: {
            readonly authUrl: "https://slack.com/oauth/v2/authorize";
            readonly tokenUrl: "https://slack.com/api/oauth.v2.access";
            readonly profileUrl: "https://slack.com/api/users.identity";
            readonly revokeUrl: "https://slack.com/api/auth.revoke";
        };
        readonly capabilities: {
            readonly pkce: false;
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly notion: {
        readonly name: "Notion";
        readonly color: "#000000";
        readonly icon: "notion";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["read", "write"];
        };
        readonly endpoints: {
            readonly authUrl: "https://api.notion.com/v1/oauth/authorize";
            readonly tokenUrl: "https://api.notion.com/v1/oauth/token";
            readonly profileUrl: "https://api.notion.com/v1/users/me";
            readonly revokeUrl: "https://api.notion.com/v1/oauth/revoke";
        };
        readonly capabilities: {
            readonly pkce: false;
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly medium: {
        readonly name: "Medium";
        readonly color: "#000000";
        readonly icon: "medium";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["basicProfile", "publishPost", "listPublications"];
        };
        readonly endpoints: {
            readonly authUrl: "https://medium.com/m/oauth/authorize";
            readonly tokenUrl: "https://medium.com/v1/tokens";
            readonly profileUrl: "https://medium.com/v1/me";
            readonly revokeUrl: "https://medium.com/v1/tokens/revoke";
        };
        readonly capabilities: {
            readonly pkce: false;
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly twitter: {
        readonly name: "X";
        readonly color: "#000000";
        readonly icon: "twitter";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["tweet.read", "users.read", "follows.read", "tweet.write", "like.write"];
        };
        readonly endpoints: {
            readonly authUrl: "https://twitter.com/i/oauth2/authorize";
            readonly tokenUrl: "https://api.twitter.com/2/oauth2/token";
            readonly profileUrl: "https://api.twitter.com/2/users/me";
            readonly revokeUrl: "https://api.twitter.com/2/oauth2/revoke";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly mastodon: {
        readonly name: "Mastodon";
        readonly color: "#6364FF";
        readonly icon: "mastodon";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["read", "write", "follow", "push"];
        };
        readonly endpoints: {
            readonly authUrl: "";
            readonly tokenUrl: "";
            readonly profileUrl: "";
            readonly revokeUrl: "";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly youtube: {
        readonly name: "YouTube";
        readonly color: "#FF0000";
        readonly icon: "youtube";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["https://www.googleapis.com/auth/youtube.readonly", "https://www.googleapis.com/auth/youtube.upload", "https://www.googleapis.com/auth/youtube.force-ssl"];
        };
        readonly endpoints: {
            readonly authUrl: "https://accounts.google.com/o/oauth2/v2/auth";
            readonly tokenUrl: "https://oauth2.googleapis.com/token";
            readonly profileUrl: "https://www.googleapis.com/youtube/v3/channels";
            readonly revokeUrl: "https://oauth2.googleapis.com/revoke";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
    readonly supabase: {
        readonly name: "Supabase";
        readonly color: "#3ECF8E";
        readonly icon: "supabase";
        readonly type: "oauth";
        readonly scopes: {
            readonly 'api-access': readonly ["auth:read", "auth:write", "database:read", "database:write", "domains:read", "domains:write", "edge_functions:read", "edge_functions:write", "environment:read", "environment:write", "organizations:read", "projects:read", "projects:write", "rest:read", "rest:write", "secrets:read", "secrets:write", "storage:read"];
        };
        readonly endpoints: {
            readonly authUrl: "https://api.supabase.com/v1/oauth/authorize";
            readonly tokenUrl: "https://api.supabase.com/v1/oauth/token";
            readonly profileUrl: "";
            readonly revokeUrl: "";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#F1F3F5";
            readonly textColor: "#11181C";
            readonly borderColor: "#E6E8EB";
            readonly hoverBackgroundColor: "#E6E8EB";
            readonly focusOutlineColor: "#3ECF8E";
            readonly fontWeight: "500";
        };
    };
    readonly vercel: {
        readonly name: "Vercel";
        readonly color: "#000000";
        readonly icon: "vercel";
        readonly type: "oauth";
        readonly scopes: {
            readonly authentication: readonly ["openid", "email", "profile", "offline_access"];
            readonly 'api-access': readonly ["project", "project-env-vars", "deployment", "team", "user"];
        };
        readonly endpoints: {
            readonly authUrl: "https://vercel.com/oauth/authorize";
            readonly tokenUrl: "https://api.vercel.com/login/oauth/token";
            readonly profileUrl: "https://api.vercel.com/login/oauth/userinfo";
            readonly revokeUrl: "https://api.vercel.com/login/oauth/token/revoke";
        };
        readonly capabilities: {
            readonly pkce: true;
            readonly codeChallengeMethod: "S256";
        };
        readonly button: {
            readonly backgroundColor: "#ffffff";
            readonly textColor: "#000000";
            readonly borderColor: "#d1d5db";
            readonly hoverBackgroundColor: "#f9fafb";
            readonly focusOutlineColor: "#3b82f6";
            readonly fontWeight: "500";
        };
    };
};
/**
 * Validates authentication partners configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateAuthPartners(): v.SafeParseResult<v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
    readonly type: v.PicklistSchema<["auth", "both"], undefined>;
    readonly scopes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    readonly firebaseProviderId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly name: v.StringSchema<undefined>;
    readonly color: v.StringSchema<undefined>;
    readonly icon: v.StringSchema<undefined>;
    readonly customParameters: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
    readonly button: v.ObjectSchema<{
        readonly backgroundColor: v.StringSchema<undefined>;
        readonly textColor: v.StringSchema<undefined>;
        readonly borderColor: v.StringSchema<undefined>;
        readonly hoverBackgroundColor: v.StringSchema<undefined>;
        readonly focusOutlineColor: v.StringSchema<undefined>;
        readonly fontWeight: v.OptionalSchema<v.StringSchema<undefined>, "500">;
        readonly textKey: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>;
}, undefined>, undefined>>;
/**
 * Validates OAuth partners configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateOAuthPartners(): v.SafeParseResult<v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
    readonly type: v.PicklistSchema<["oauth", "both"], undefined>;
    readonly scopes: v.ObjectSchema<{
        readonly authentication: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly 'api-access': v.ArraySchema<v.StringSchema<undefined>, undefined>;
    }, undefined>;
    readonly endpoints: v.ObjectSchema<{
        readonly authUrl: v.UnionSchema<[v.LiteralSchema<"", undefined>, v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>], undefined>;
        readonly tokenUrl: v.UnionSchema<[v.LiteralSchema<"", undefined>, v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>], undefined>;
        readonly profileUrl: v.UnionSchema<[v.LiteralSchema<"", undefined>, v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>], undefined>;
        readonly revokeUrl: v.OptionalSchema<v.UnionSchema<[v.LiteralSchema<"", undefined>, v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>], undefined>, undefined>;
    }, undefined>;
    readonly capabilities: v.OptionalSchema<v.ObjectSchema<{
        readonly pkce: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
        readonly codeChallengeMethod: v.OptionalSchema<v.PicklistSchema<["S256", "plain"], undefined>, "S256">;
    }, undefined>, undefined>;
    readonly name: v.StringSchema<undefined>;
    readonly color: v.StringSchema<undefined>;
    readonly icon: v.StringSchema<undefined>;
    readonly customParameters: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
    readonly button: v.ObjectSchema<{
        readonly backgroundColor: v.StringSchema<undefined>;
        readonly textColor: v.StringSchema<undefined>;
        readonly borderColor: v.StringSchema<undefined>;
        readonly hoverBackgroundColor: v.StringSchema<undefined>;
        readonly focusOutlineColor: v.StringSchema<undefined>;
        readonly fontWeight: v.OptionalSchema<v.StringSchema<undefined>, "500">;
        readonly textKey: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    }, undefined>;
}, undefined>, undefined>>;
/**
 * Authentication partner ID type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthPartnerId = keyof typeof AUTH_PARTNERS;
/**
 * OAuth partner ID type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthPartnerId = keyof typeof OAUTH_PARTNERS;
/**
 * Partner ID type (auth or OAuth)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PartnerId = AuthPartnerId | OAuthPartnerId;
/**
 * Authentication partner type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthPartner = v.InferOutput<typeof authPartnerSchema>;
/**
 * OAuth partner type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthPartner = (typeof OAUTH_PARTNERS)[OAuthPartnerId];
/**
 * Checks if a partner ID is an authentication partner
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function isAuthPartnerId(id: PartnerId): id is AuthPartnerId;
/**
 * Checks if a partner ID is an OAuth partner
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function isOAuthPartnerId(id: PartnerId): id is OAuthPartnerId;

/**
 * @fileoverview Types for Authentication Partners
 * @description Extends existing auth types with partner-based authentication. Defines partner result types, connection states, partner buttons, and partner-related interfaces.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Shared primitives for auth and oauth partner flows
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PartnerResult {
    success: boolean;
    error?: string;
    userInfo?: {
        id: string;
        name?: string;
        username?: string;
        email?: string;
        photoURL?: string;
    };
}
/**
 * Partner connection state interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PartnerConnectionState {
    isConnecting: boolean;
    isConnected: boolean;
    error: Error | null;
}

/**
 * @fileoverview Authentication Constants
 * @description Constants for authentication domain. Defines token status types, user roles, subscription tiers, features, permissions, and authentication-related constants.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Token status possible values
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type TokenStatus = 'valid' | 'expiring-soon' | 'expired' | 'error' | 'not-initialized';
/**
 * Authentication status type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthStatus = 'authenticated' | 'unauthenticated' | 'loading';
/**
 * Standard user role names
 * Apps can override these by providing their own role constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const USER_ROLES: {
    readonly GUEST: "guest";
    readonly USER: "user";
    readonly ADMIN: "admin";
    readonly SUPER: "super";
};
/**
 * Override user roles for custom app needs
 * @example
 * ```typescript
 * // In your app's config
 * overrideUserRoles({
 *   GUEST: 'visitor',
 *   USER: 'member',
 *   ADMIN: 'moderator'
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function overrideUserRoles(customRoles: Partial<typeof USER_ROLES>): void;
/**
 * Type for user role names
 * Apps can extend this with their own custom roles
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type UserRole = (typeof USER_ROLES)[keyof typeof USER_ROLES] | string;
/**
 * Standard subscription tier names
 * Apps can override these by providing their own tier constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const SUBSCRIPTION_TIERS: {
    readonly FREE: "free";
    readonly PRO: "pro";
    readonly PREMIUM: "premium";
};
/**
 * Override subscription tiers for custom app needs
 * @example
 * ```typescript
 * // In your app's config
 * overrideSubscriptionTiers({
 *   FREE: 'basic',
 *   PRO: 'professional',
 *   PREMIUM: 'enterprise'
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function overrideSubscriptionTiers(customTiers: Partial<typeof SUBSCRIPTION_TIERS>): void;
/**
 * Type for subscription tier names
 * Apps can extend this with their own custom tiers
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type SubscriptionTier = (typeof SUBSCRIPTION_TIERS)[keyof typeof SUBSCRIPTION_TIERS] | string;
/**
 * Standard feature names
 * Apps can override these by providing their own feature constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const FEATURES: {
    readonly BASIC_ACCESS: "basic_access";
    readonly ADVANCED_FEATURES: "advanced_features";
    readonly API_ACCESS: "api_access";
    readonly PRIORITY_SUPPORT: "priority_support";
};
/**
 * Override features for custom app needs
 * @example
 * ```typescript
 * // In your app's config
 * overrideFeatures({
 *   BASIC_ACCESS: 'read_access',
 *   ADVANCED_FEATURES: 'write_access',
 *   API_ACCESS: 'api_calls',
 *   PRIORITY_SUPPORT: 'dedicated_support'
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function overrideFeatures(customFeatures: Partial<typeof FEATURES>): void;
/**
 * Type for feature names
 * Apps can extend this with their own custom features
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FeatureId = (typeof FEATURES)[keyof typeof FEATURES] | string;
/**
 * Standard permission names
 * Apps can override these by providing their own permission constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const PERMISSIONS: {
    readonly READ_PUBLIC: "read_public";
    readonly READ_OWN_DATA: "read_own_data";
    readonly WRITE_OWN_DATA: "write_own_data";
    readonly READ_ALL_DATA: "read_all_data";
    readonly MANAGE_USERS: "manage_users";
};
/**
 * Override permissions for custom app needs
 * @example
 * ```typescript
 * // In your app's config
 * overridePermissions({
 *   READ_PUBLIC: 'view_public',
 *   READ_OWN_DATA: 'view_profile',
 *   WRITE_OWN_DATA: 'edit_profile',
 *   READ_ALL_DATA: 'view_all',
 *   MANAGE_USERS: 'admin_users'
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function overridePermissions(customPermissions: Partial<typeof PERMISSIONS>): void;
/**
 * Type for permission names
 * Apps can extend this with their own custom permissions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type Permission = (typeof PERMISSIONS)[keyof typeof PERMISSIONS] | string;
/**
 * A map containing instances of authentication providers.
 * Uses schema discovery to support all AUTH_PARTNERS automatically.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ProviderInstances = Record<AuthPartnerId, any>;

/**
 * @fileoverview Schema Definitions for Authentication and User Management
 * @description Single source of truth for all auth-related data validation. Defines validation schemas for authentication, user management, and related data structures.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Schema for authenticated user data
 * Uses constants for enum values to ensure consistency
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const AuthUserSchema: v.ObjectSchema<{
    readonly id: v.StringSchema<undefined>;
    readonly email: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>, undefined>;
    readonly displayName: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
    readonly photoURL: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>, undefined>;
    readonly emailVerified: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly lastLoginAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly providerData: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
        readonly providerId: v.StringSchema<undefined>;
        readonly uid: v.StringSchema<undefined>;
        readonly email: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>, undefined>;
        readonly displayName: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly photoURL: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>, undefined>;
        readonly phoneNumber: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
    }, undefined>, undefined>, undefined>;
    readonly role: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>;
    readonly customClaims: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>, undefined>;
}, undefined>;
/**
 * Schema for user subscription data
 * Uses constants for enum values to ensure consistency
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const UserSubscriptionSchema: v.ObjectSchema<{
    readonly userId: v.StringSchema<undefined>;
    readonly tier: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly isActive: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
    readonly customerId: v.StringSchema<undefined>;
    readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
    readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
    readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
}, undefined>;
/**
 * Schema for Firebase Auth custom claims
 * Uses constants for enum values to ensure consistency
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const CustomClaimsSchema: v.ObjectSchema<{
    readonly role: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>;
    readonly subscription: v.OptionalSchema<v.ObjectSchema<{
        readonly userId: v.StringSchema<undefined>;
        readonly tier: v.PicklistSchema<[string, ...string[]], undefined>;
        readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
        readonly isActive: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
        readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
        readonly customerId: v.StringSchema<undefined>;
        readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
        readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
        readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
    }, undefined>, undefined>;
    readonly features: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>, undefined>;
    readonly permissions: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>, undefined>;
    readonly githubAccess: v.OptionalSchema<v.ObjectSchema<{
        readonly username: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly teamAccess: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly repoAccess: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    }, undefined>, undefined>;
}, undefined>;
/**
 * Type for authenticated user data
 * Automatically derived from schema
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthUser = v.InferOutput<typeof AuthUserSchema>;
/**
 * Type for user subscription data
 * Automatically derived from schema
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type UserSubscription = v.InferOutput<typeof UserSubscriptionSchema>;
/**
 * Type for Firebase Auth custom claims
 * Automatically derived from schema
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CustomClaims = v.InferOutput<typeof CustomClaimsSchema>;
/**
 * Validate auth user data
 * @param data - Data to validate
 * @returns Validation result with success/error information
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateAuthUser(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly id: v.StringSchema<undefined>;
    readonly email: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>, undefined>;
    readonly displayName: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
    readonly photoURL: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>, undefined>;
    readonly emailVerified: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly lastLoginAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly providerData: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
        readonly providerId: v.StringSchema<undefined>;
        readonly uid: v.StringSchema<undefined>;
        readonly email: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>, undefined>;
        readonly displayName: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly photoURL: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>, undefined>;
        readonly phoneNumber: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
    }, undefined>, undefined>, undefined>;
    readonly role: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>;
    readonly customClaims: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>, undefined>;
}, undefined>>;
/**
 * Validate user subscription data
 * @param data - Data to validate
 * @returns Validation result with success/error information
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateUserSubscription(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly userId: v.StringSchema<undefined>;
    readonly tier: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly isActive: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
    readonly customerId: v.StringSchema<undefined>;
    readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
    readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
    readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
}, undefined>>;
/**
 * Validate custom claims data
 * @param data - Data to validate
 * @returns Validation result with success/error information
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateCustomClaims(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly role: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>;
    readonly subscription: v.OptionalSchema<v.ObjectSchema<{
        readonly userId: v.StringSchema<undefined>;
        readonly tier: v.PicklistSchema<[string, ...string[]], undefined>;
        readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
        readonly isActive: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
        readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
        readonly customerId: v.StringSchema<undefined>;
        readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
        readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
        readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
    }, undefined>, undefined>;
    readonly features: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>, undefined>;
    readonly permissions: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>, undefined>;
    readonly githubAccess: v.OptionalSchema<v.ObjectSchema<{
        readonly username: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly teamAccess: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        readonly repoAccess: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    }, undefined>, undefined>;
}, undefined>>;
/**
 * Validate that all schemas are properly configured
 * Only runs when explicitly called during development
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateAuthSchemas(): {
    success: boolean;
    results: {
        authUser: v.SafeParseResult<v.ObjectSchema<{
            readonly id: v.StringSchema<undefined>;
            readonly email: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>, undefined>;
            readonly displayName: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
            readonly photoURL: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>, undefined>;
            readonly emailVerified: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
            readonly lastLoginAt: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
            readonly providerData: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
                readonly providerId: v.StringSchema<undefined>;
                readonly uid: v.StringSchema<undefined>;
                readonly email: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>, undefined>;
                readonly displayName: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
                readonly photoURL: v.OptionalSchema<v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>, undefined>;
                readonly phoneNumber: v.OptionalSchema<v.NullableSchema<v.StringSchema<undefined>, undefined>, undefined>;
            }, undefined>, undefined>, undefined>;
            readonly role: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>;
            readonly customClaims: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>, undefined>;
        }, undefined>>;
        userSubscription: v.SafeParseResult<v.ObjectSchema<{
            readonly userId: v.StringSchema<undefined>;
            readonly tier: v.PicklistSchema<[string, ...string[]], undefined>;
            readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
            readonly isActive: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
            readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
            readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
            readonly customerId: v.StringSchema<undefined>;
            readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
            readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
            readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
        }, undefined>>;
        customClaims: v.SafeParseResult<v.ObjectSchema<{
            readonly role: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>;
            readonly subscription: v.OptionalSchema<v.ObjectSchema<{
                readonly userId: v.StringSchema<undefined>;
                readonly tier: v.PicklistSchema<[string, ...string[]], undefined>;
                readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
                readonly isActive: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
                readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
                readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
                readonly customerId: v.StringSchema<undefined>;
                readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
                readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
                readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
            }, undefined>, undefined>;
            readonly features: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>, undefined>;
            readonly permissions: v.OptionalSchema<v.ArraySchema<v.PicklistSchema<[string, ...string[]], undefined>, undefined>, undefined>;
            readonly githubAccess: v.OptionalSchema<v.ObjectSchema<{
                readonly username: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
                readonly teamAccess: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
                readonly repoAccess: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
            }, undefined>, undefined>;
        }, undefined>>;
        getUserAuthStatus: v.SafeParseResult<v.ObjectSchema<{
            readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
        }, undefined>>;
        getCustomClaims: v.SafeParseResult<v.ObjectSchema<{
            readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
            readonly claimKeys: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
        }, undefined>>;
        setCustomClaims: v.SafeParseResult<v.ObjectSchema<{
            readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
            readonly claims: v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>;
            readonly merge: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
        }, undefined>>;
        removeCustomClaims: v.SafeParseResult<v.ObjectSchema<{
            readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
            readonly claimKeys: v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.MinLengthAction<string[], 1, undefined>]>;
        }, undefined>>;
    };
};

/**
 * @fileoverview Server Auth Adapter Interface
 * @description Provider-agnostic interface for server-side authentication.
 * Token verification, user lookup, and custom claims management.
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */
/** Result of token verification */
interface VerifiedToken {
    /** The user's unique identifier */
    uid: string;
    /** Optional: email from the token */
    email?: string;
    /** Optional: additional claims embedded in the token */
    claims?: Record<string, unknown>;
}
/** Server-side user record (minimal) */
interface ServerUserRecord {
    uid: string;
    email?: string;
    displayName?: string;
    customClaims?: Record<string, unknown>;
}
/**
 * Provider-agnostic server-side auth adapter.
 *
 * Implementations:
 * - `FirebaseServerAuthAdapter` (Firebase Admin SDK)
 * - Future: Supabase server auth, Auth.js, custom JWT adapters
 *
 * @version 0.1.0
 * @since 0.5.0
 */
interface IServerAuthAdapter {
    /** Verify an auth token and return the decoded user info. Throws on invalid token. */
    verifyToken(token: string): Promise<VerifiedToken>;
    /** Get a user record by UID. Returns null if not found. */
    getUser(uid: string): Promise<ServerUserRecord | null>;
    /** Set custom claims on a user (merge semantics — existing claims are preserved unless overwritten). */
    setCustomClaims(uid: string, claims: Record<string, unknown>): Promise<void>;
}

/**
 * @fileoverview Layout Constants
 * @description Shared constants and derived types used by both layoutTypes and presetConfig.
 * Extracted to break circular dependency.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Default layout preset - single source of truth
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const DEFAULT_LAYOUT_PRESET: "landing";
/**
 * Footer mode constants - DRY single source of truth
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const FOOTER_MODE: {
    readonly FIXED: "fixed";
    readonly SCROLL: "scroll";
};
/**
 * Footer mode type - auto-derived from constants
 */
type FooterMode = (typeof FOOTER_MODE)[keyof typeof FOOTER_MODE];
/**
 * Layout preset constants - DRY single source of truth
 * Use these instead of hardcoded strings throughout the codebase
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const LAYOUT_PRESET: {
    readonly ADMIN: "admin";
    readonly BLOG: "blog";
    readonly DOCS: "docs";
    readonly GAME: "game";
    readonly LANDING: "landing";
    readonly MOOLTI: "moolti";
    readonly PLAIN: "plain";
};
/**
 * Layout preset type - auto-derived from constants, with string fallback
 * Accepts known presets OR any string (runtime validates and defaults to 'landing')
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type LayoutPreset = (typeof LAYOUT_PRESET)[keyof typeof LAYOUT_PRESET] | string;

/**
 * @fileoverview Preset Configuration Types
 * @description Config-based preset system types. Presets are configuration objects
 * that declare what components go in which slots, replacing the component-based approach.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Slot content function - returns ReactNode or null
 *
 * Presets use functions that return ReactNode, same API as consumers.
 * Return null to explicitly hide the slot.
 */
type SlotContent = () => ReactNode | null;
/**
 * Header zone configuration
 *
 * Grid-based layout with start/center/end areas.
 * - start: start-aligned (typically branding: AppIcon, AppTitle)
 * - center: absolutely centered (overlay, regardless of start/end content)
 * - end: end-aligned (typically actions: GoTo, Auth, Language, Theme)
 */
interface HeaderZoneConfig {
    /** Start slot - start-aligned, typically branding (AppIcon, AppTitle) */
    start?: SlotContent;
    /** Center slot - absolutely centered overlay, optional (navigation, search) */
    center?: SlotContent;
    /** End slot - end-aligned, typically actions (GoTo, Auth, Language, Theme) */
    end?: SlotContent;
}
/**
 * Sidebar zone configuration
 *
 * Vertical layout with top/content/bottom areas.
 * All sidebars use ResizableSidebar wrapper.
 */
interface SidebarZoneConfig {
    /** Top slot - branding, search */
    top?: SlotContent;
    /** Content slot - main scrollable area (defaults to NavigationMenu) */
    content?: SlotContent;
    /** Bottom slot - user profile, settings */
    bottom?: SlotContent;
    /** Default sidebar width in pixels */
    defaultWidth?: number;
    /** Minimum width when resizing */
    minWidth?: number;
    /** Maximum width when resizing */
    maxWidth?: number;
}
/**
 * Footer zone configuration
 *
 * Simple footer: Copyright (left) | LegalLinks + DoNotDev (right)
 * - `null`: Hide footer
 * - `undefined`: Use defaults (copyright + legal links + DoNotDev)
 * - `{ copyright?: ..., legalLinks?: ... }`: Custom configuration
 */
interface FooterConfig {
    /** Copyright configuration
     * - `null`: Hide copyright
     * - `undefined`: Use default (© YEAR appName. All rights reserved)
     * - `string`: Custom copyright text
     */
    copyright?: null | string;
    /** Legal links configuration
     * - `null`: Hide legal links
     * - `Array<{ path, label }>`: Custom legal links
     * - `undefined`: Use framework defaults
     */
    legalLinks?: null | Array<{
        path: string;
        label: string;
    }>;
}
/**
 * Footer zone configuration
 *
 * - `FooterConfig` object: configure DnDevFooter (copyright, legal links)
 * - `SlotContent` function: replace DnDevFooter with custom component
 * - `null`: hide footer
 * - `undefined`: use defaults
 */
type FooterZoneConfig = FooterConfig | SlotContent | null;
/**
 * MergedBar configuration for mobile
 *
 * Fixed trigger bar that opens a Sheet with navigation content.
 * Each slot is customizable per-preset, with smart defaults.
 */
interface MergedBarConfig {
    /** Position of the trigger bar */
    position: 'top' | 'bottom';
    /** Height of the trigger bar (default: 64px for top, 48px for bottom) */
    height?: string;
    /** Trigger bar content (default: header.start for top, footer-like for bottom) */
    trigger?: SlotContent;
    /** Sheet top slot */
    top?: SlotContent;
    /** Sheet content slot - scrollable (default: sidebar.content) */
    content?: SlotContent;
    /** Sheet bottom slot (default: sidebar.bottom) */
    bottom?: SlotContent;
}
/**
 * Mobile behavior configuration
 *
 * Defines how the layout adapts on mobile/tablet breakpoints.
 */
interface MobileBehaviorConfig {
    /** Breakpoint at which mobile behavior activates (default: 1024px) */
    breakpoint?: number;
    /** Header slot overrides for mobile (overrides desktop header slots) */
    header?: HeaderZoneConfig;
    /** Sidebar slot overrides for mobile (overrides desktop sidebar slots) */
    sidebar?: SidebarZoneConfig;
    /** MergedBar configuration - replaces header/footer with sheet trigger */
    mergedBar?: MergedBarConfig;
}
/**
 * Complete preset configuration
 *
 * Declarative configuration for a layout preset.
 * Uses function-based slots, same API as consumers.
 *
 * @example
 * ```typescript
 * const landingPreset: PresetConfig = {
 *   name: 'landing',
 *   header: {
 *     start: () => <AppBranding />,
 *     center: () => null,
 *     end: () => (
 *       <>
 *         <GoTo />
 *         <AuthHeader />
 *       </>
 *     ),
 *   },
 *   mobile: {
 *     header: {
 *       end: () => <HeaderMenu>{desktop end content}</HeaderMenu>,
 *     },
 *   },
 * };
 * ```
 */
interface PresetConfig {
    /** Preset identifier (must match LayoutPreset type) */
    name: LayoutPreset;
    /** Header zone configuration (undefined = use defaults, object = override slots, function = custom mode) */
    header?: HeaderZoneConfig | SlotContent;
    /** Sidebar zone configuration (undefined = use defaults, object = override slots, function = custom mode) */
    sidebar?: SidebarZoneConfig | SlotContent;
    /** Footer zone configuration (undefined = use defaults, object = override) */
    footer?: FooterZoneConfig;
    /** Footer scroll behavior override for this preset */
    footerMode?: FooterMode;
    /** Mobile behavior configuration */
    mobile?: MobileBehaviorConfig;
}
/**
 * Preset registry type
 *
 * Maps preset names to their configurations.
 */
type PresetRegistry = Record<LayoutPreset, PresetConfig>;

/**
 * @fileoverview Layout Types
 * @description Type definitions for layout system. Defines layout presets, layout configuration, zone configuration, and layout-related interfaces.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Layout preset string literals
 *
 * Each preset provides a different layout configuration optimized for specific use cases:
 * - 'landing': Marketing site with header and footer (default)
 * - 'admin': Admin panel with header, sidebar, and footer
 * - 'docs': Documentation with header, sidebar, and footer
 * - 'blog': Blog with header, sidebar, and footer
 * - 'moolti': SaaS app with sidebar only
 * - 'game': Mobile gaming with fixed header/footer (64px/24px)
 * - 'plain': Minimal layout with no UI chrome
 */
/**
 * Layout slot configuration for customizing layout zones
 *
 * Provides a clean, typed interface for customizing different areas of the layout
 * without prop drilling. Each preset uses only the slots it supports.
 *
 * Slots are functions that return ReactNode - this ensures hooks run after
 * providers are ready, preventing timing issues with feature-gated components.
 * Functions are called when the framework renders, ensuring all providers
 * and stores are initialized before component hooks execute.
 *
 * @example
 * ```typescript
 * const layout: LayoutConfig = {
 *   header: {
 *     start: () => <MyLogo />,
 *     end: () => <MyActions />
 *   },
 *   footer: () => <CustomFooter />
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Layout override function - lazy component renderer
 *
 * Consumers use this to override layout zones/slots.
 * Function ensures components load lazily, not in provider tree.
 * Return `null` to explicitly hide the slot.
 */
type DnDevOverride = () => ReactNode | null;
/**
 * Main content wrapper component
 *
 * Wraps the page content (`children` / `<Outlet />`) inside `<main>`.
 * Use to add custom chrome around page content without modifying the framework layout:
 * split panes, floating panels, contextual sidebars, terminal docking, etc.
 *
 * Receives page content as `children`. Breadcrumbs, debug tools, and footer
 * remain outside the wrapper (framework-managed).
 *
 * Works identically with Vite (`<Outlet />`) and Next.js (`{children}`).
 *
 * @example
 * ```tsx
 * // Vite — split pane with terminal
 * <ViteAppProviders
 *   layout={{
 *     wrapper: ({ children }) => (
 *       <SplitLayout terminal={<TerminalPanel />}>
 *         {children}
 *       </SplitLayout>
 *     ),
 *   }}
 * />
 *
 * // Next.js — admin panel with contextual sidebar
 * <NextJsAppProviders
 *   layout={{
 *     wrapper: ({ children }) => (
 *       <AdminPanel sidebar={<ContextNav />}>{children}</AdminPanel>
 *     ),
 *   }}
 * />
 * ```
 */
type DnDevWrapper = (props: {
    children: ReactNode;
}) => ReactNode | null;
/**
 * Layout configuration - simple API for consumers
 *
 * @example
 * ```typescript
 * layout={{
 *   preset: 'admin',
 *   header: { end: () => <MyButton /> }
 * }}
 * ```
 */
interface LayoutConfig {
    /** Breadcrumbs display behavior */
    breadcrumbs?: 'smart' | 'always' | 'never';
    /**
     * Footer scroll behavior
     * - 'fixed': Footer stays at viewport bottom (default on desktop)
     * - 'scroll': Footer scrolls with content (default on mobile, optional on desktop)
     */
    footerMode?: FooterMode;
    /** Header override - full component or slot overrides */
    header?: DnDevOverride | {
        start?: DnDevOverride;
        center?: DnDevOverride;
        end?: DnDevOverride;
    };
    /** Footer override - full component only */
    footer?: DnDevOverride;
    /** Sidebar override - full component or slot overrides */
    sidebar?: DnDevOverride | {
        top?: DnDevOverride;
        content?: DnDevOverride;
        bottom?: DnDevOverride;
    };
    /** MergedBar override - full component or slot overrides */
    mergedbar?: DnDevOverride | {
        trigger?: DnDevOverride;
        top?: DnDevOverride;
        content?: DnDevOverride;
        bottom?: DnDevOverride;
    };
    /**
     * Main content wrapper — wraps page content inside `<main>`
     *
     * Add custom chrome around page content (split panes, floating panels,
     * terminal docking) without modifying the framework layout.
     * Breadcrumbs, debug tools, and footer remain outside the wrapper.
     *
     * Works with both Vite and Next.js routing.
     *
     * @example
     * ```tsx
     * layout={{
     *   wrapper: ({ children }) => (
     *     <SplitLayout terminal={<Terminal />}>{children}</SplitLayout>
     *   ),
     * }}
     * ```
     */
    wrapper?: DnDevWrapper;
    /** Mobile-specific overrides */
    mobile?: {
        /** Mobile header slot overrides (overrides desktop header on mobile) */
        header?: {
            start?: DnDevOverride;
            center?: DnDevOverride;
            end?: DnDevOverride;
        };
        /** Mobile sidebar slot overrides (overrides desktop sidebar on mobile) */
        sidebar?: {
            top?: DnDevOverride;
            content?: DnDevOverride;
            bottom?: DnDevOverride;
        };
    };
}
/**
 * App metadata and branding configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AppMetadata {
    /** Application name */
    name?: string;
    /** Short application name for mobile/compact displays (defaults to name if not set) */
    shortName?: string;
    /** Application description */
    description?: string;
    /** Social and external links */
    links?: {
        /** GitHub repository URL */
        github?: string;
        /** Twitter/X profile URL */
        twitter?: string;
        /** LinkedIn profile URL */
        linkedin?: string;
        /** Support/contact URL */
        support?: string;
        /** Documentation URL */
        docs?: string;
        /** Blog URL */
        blog?: string;
    };
    /** Footer configuration
     * - `null`: Explicitly hide footer
     * - `undefined`: Use framework default footer
     * - `{ copyright?: ..., legalLinks?: ... }`: Custom footer configuration
     */
    footer?: {
        /** Copyright configuration
         * - `null`: Hide copyright
         * - `undefined`: Use default (© YEAR appName. All rights reserved)
         * - `string`: Custom copyright text
         */
        copyright?: null | string;
        /** Legal links configuration
         * - `null`: Hide legal links
         * - `Array<{ path, label }>`: Custom legal links (labels can be i18n keys via maybeTranslate)
         * - `undefined`: Use framework defaults (Privacy Policy, Terms of Service with i18n labels)
         */
        legalLinks?: null | Array<{
            path: string;
            label: string;
        }>;
    } | null;
    /** Additional application metadata */
    metadata?: Record<string, any>;
}
/**
 * Authentication route configuration
 *
 * Configure redirect routes for authentication and authorization failures.
 * Also configures AuthHeader UI behavior (login page, user menu, etc.).
 * All routes are optional with security-first defaults.
 *
 * @example
 * ```typescript
 * const authConfig: AuthConfig = {
 *   authRoute: '/signin',
 *   roleRoute: '/403',
 *   tierRoute: '/pricing',
 *   loginPath: '/login',  // Optional: links to login page (undefined = show providers in header)
 *   profilePath: '/account',
 *   authMenuPaths: ['/dashboard', '/settings']
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthConfig {
    /** Route to redirect when authentication required (default: '/') */
    authRoute?: string;
    /** Route to redirect when role insufficient (default: '/404') */
    roleRoute: string;
    /** Route to redirect when tier insufficient (default: '/404') */
    tierRoute: string;
    /** Optional: Path to login page. If provided, AuthHeader links to login page. If undefined (default), shows providers in header */
    loginPath?: string;
    /** Optional: Path to password reset callback page (default: '/auth/reset-password'). Framework auto-handles the route. */
    resetPasswordPath?: string;
    /** Optional: Path to profile page (default: '/profile') */
    profilePath?: string;
    /**
     * Optional: Custom menu items for authenticated user menu dropdown.
     * Supports route-based items with paths (auto-creates Link).
     * Icons are auto-resolved from route discovery (PageMeta.icon) if not provided.
     * For items with onClick handlers, use AuthMenu customItems prop instead.
     *
     * @example
     * ```typescript
     * authMenuItems: [
     *   { path: '/dashboard' }, // icon auto-resolved from route
     *   { path: '/settings', label: 'Settings' }, // override label, icon from route
     *   { path: '/billing', icon: 'CreditCard' } // override icon
     * ]
     * ```
     */
    authMenuItems?: Array<{
        /** Route path (creates Link automatically) */
        path: string;
        /** Optional label (falls back to navigation item label or path segment) */
        label?: string;
        /** Optional Lucide icon name (string) - overrides route discovery icon */
        icon?: string;
    }>;
    /**
     * Optional function to handle custom data deletion before account removal
     * Framework will try/catch this - failures won't block account deletion
     *
     * @example
     * ```typescript
     * deleteUserFunction: async (userId: string) => {
     *   // Cancel Stripe subscriptions
     *   await fetch('/api/billing/cancel', { method: 'POST' });
     *
     *   // Delete Firestore user data
     *   await deleteDoc(doc(db, 'users', userId));
     *
     *   // Custom cleanup
     *   await myCustomCleanup(userId);
     * }
     * ```
     */
    deleteUserFunction?: (userId: string) => Promise<void>;
}
/**
 * SEO configuration
 *
 * Configure automatic SEO meta tags and social sharing.
 *
 * @example
 * ```typescript
 * const seoConfig: SEOConfig = {
 *   baseUrl: 'https://example.com',
 *   defaultImage: '/og-image.png',
 *   twitterHandle: 'mycompany'
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SEOConfig {
    /** Enable automatic SEO (default: true) */
    enabled?: boolean;
    /** Base URL for SEO files (robots.txt, sitemap.xml) - reads from VITE_APP_URL/NEXT_PUBLIC_APP_URL env var */
    baseUrl?: string;
    /** Site name for SEO - defaults to APP_NAME from app.ts */
    siteName?: string;
    /** Crawl delay for robots.txt (default: 1) */
    crawlDelay?: number;
    /** Generate robots.txt (default: true) */
    generateRobotsTxt?: boolean;
    /** Generate sitemap.xml (default: true) */
    generateSitemap?: boolean;
    /** Default namespace for i18n translations (default: 'home') */
    defaultNamespace?: string;
    /** Default image for social sharing */
    defaultImage?: string;
    /** Twitter handle (without @) */
    twitterHandle?: string;
    /** Additional static meta tags */
    staticTags?: Record<string, string>;
    /** URL redirect rules - generates platform-specific 301/302 redirects at build time */
    redirects?: Array<{
        /** Source path (supports :param syntax, e.g. '/old-blog/:slug') */
        from: string;
        /** Destination path (supports :param syntax, e.g. '/blog/:slug') */
        to: string;
        /** true = 301 permanent (default), false = 302 temporary */
        permanent?: boolean;
    }>;
    /**
     * AI crawler management in robots.txt (default: 'recommended')
     * - 'recommended': Block training bots (GPTBot, Google-Extended, CCBot, ClaudeBot),
     *   allow search/retrieval bots (OAI-SearchBot, ChatGPT-User, Claude-SearchBot, etc.)
     * - 'block-all': Block all AI bots
     * - 'allow-all': Allow all AI bots
     * - false: No AI crawler directives
     */
    aiCrawlers?: 'recommended' | 'block-all' | 'allow-all' | false;
    /** Generate llms.txt per llmstxt.org spec (default: true). Set to false to disable. */
    llmsTxt?: boolean;
    /** Inject Speculation Rules API for prefetch/prerender of internal links (default: true). Set to false to disable. */
    speculationRules?: boolean;
    /** Emit hreflang alternate links when i18n has 2+ languages (default: true). No-op for monolingual apps. Set to false to disable. */
    hreflang?: boolean;
    /** Auto-generate BreadcrumbList JSON-LD from URL path segments (default: true). Set to false to disable. */
    breadcrumbSchema?: boolean;
    /** Auto-generate WebSite JSON-LD with SearchAction for sitelinks search box (default: true). Set to false to disable. */
    websiteSchema?: boolean;
    /** Auto-generate Organization JSON-LD on homepage from app.links (default: true). Set to false to disable. */
    organizationSchema?: boolean;
}
/**
 * Favicon and PWA configuration
 *
 * Configure automatic favicon generation and PWA manifest icons.
 *
 * @example
 * ```typescript
 * const faviconConfig: FaviconConfig = {
 *   appName: 'My App',
 *   themeColor: '#000000',
 *   backgroundColor: '#ffffff'
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FaviconConfig {
    /** Enable automatic favicon system (default: true) */
    enabled?: boolean;
    /** App name for PWA manifest */
    appName?: string;
    /** Theme color for mobile browsers */
    themeColor?: string;
    /** Background color for splash screens */
    backgroundColor?: string;
    /** Include PWA manifest icons */
    includeManifestIcons?: boolean;
    /** Include Microsoft tile icons */
    includeMSIcons?: boolean;
}
/**
 * Feature flags and debug configuration
 *
 * Controls app behavior and GDPR compliance.
 * Feature availability is auto-detected via env vars/packages.
 *
 * @example
 * ```typescript
 * const featuresConfig: FeaturesConfig = {
 *   debug: true,
 *   offlineTrustEnabled: true,
 *   requiredCookies: ['necessary', 'analytics']
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FeaturesConfig {
    /** Enable debug tools (default: false in production, true in development) */
    debug?: boolean;
    /**
     * Enable offline trust for cached claims (default: false)
     *
     * When true:
     * - Online: Always verify with server (don't trust cache)
     * - Offline: Use cached claims (graceful degradation)
     *
     * When false:
     * - Online: Always verify with server
     * - Offline: Reject (throw error, require network)
     *
     * @default false
     */
    offlineTrustEnabled?: boolean;
    /**
     * Cookie consent categories to display in GDPR banner
     *
     * Controls which cookie categories users can consent to.
     * Framework always includes 'necessary' (cannot be disabled).
     *
     * @example
     * ```typescript
     * features: {
     *   requiredCookies: ['necessary', 'functional', 'analytics']
     * }
     * ```
     *
     * @default ['necessary']
     */
    requiredCookies?: string[];
}
/**
 * Complete application configuration
 *
 * Consolidates all app-level configuration with smart defaults.
 * Pass only what you need to override - everything has sensible defaults.
 *
 * @example
 * ```typescript
 * // Minimal configuration
 * const config: AppConfig = {
 *   app: { name: 'My App' }
 * };
 *
 * // Full configuration
 * const config: AppConfig = {
 *   app: {
 *     name: 'My App',
 *     description: 'Professional app'
 *   },
 *   auth: {
 *     authRoute: '/signin',
 *     roleRoute: '/403',
 *     tierRoute: '/pricing'
 *   },
 *   seo: {
 *     defaultImage: '/og.png'
 *   },
 *   preset: 'landing',
 *   features: {
 *     debug: true
 *   }
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Query cache configuration
 *
 * Configure default TanStack Query cache behavior for your app.
 * These settings apply to all queries unless overridden per-query.
 *
 * **Framework Defaults (Infinite Cache):**
 * - `staleTime: Infinity` (data never becomes stale)
 * - `refetchOnWindowFocus: false` (manual refresh only)
 * - `refetchOnReconnect: false` (manual refresh only)
 *
 * This default strategy minimizes API costs and is ideal for:
 * - Single-admin apps
 * - Apps with manual refresh buttons
 * - Cost-optimized scenarios
 *
 * @example
 * ```typescript
 * // Use framework defaults (infinite cache, no auto-refetch)
 * // No query config needed - defaults are optimal
 * ```
 *
 * @example
 * ```typescript
 * // Override to short cache with auto-refetch
 * query: {
 *   staleTime: 1000 * 60 * 5,  // 5 minutes
 *   refetchOnWindowFocus: true,
 *   refetchOnReconnect: true,
 * }
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface QueryConfig {
    /** Time until data is considered stale (default: Infinity = never stale) */
    staleTime?: number;
    /** Time until inactive data is garbage collected (default: 30 minutes) */
    gcTime?: number;
    /** Number of retry attempts for failed queries (default: 1) */
    retry?: number;
    /** Whether to refetch when window regains focus (default: false = manual refresh only) */
    refetchOnWindowFocus?: boolean;
    /** Whether to refetch on reconnect (default: false = manual refresh only) */
    refetchOnReconnect?: boolean;
    /** Mutation retry attempts (default: 1) */
    mutationRetry?: number;
    /** Mutation retry delay function (default: exponential backoff) */
    mutationRetryDelay?: (attemptIndex: number) => number;
}
/** Top-level application configuration passed to DoNotDevProvider. */
interface AppConfig {
    /** App metadata and branding */
    app?: AppMetadata;
    /** Authentication routes - partial override of defaults */
    auth?: Partial<AuthConfig> | false;
    /** SEO configuration (set to false to disable) */
    seo?: SEOConfig | false;
    /** Favicon configuration (set to false to disable) */
    favicon?: FaviconConfig | false;
    /** Layout preset for store initialization (defaults to 'landing' if invalid/empty) */
    preset?: string;
    /** Custom presets — same shape as built-in presets, keyed by name */
    customPresets?: Record<string, PresetConfig>;
    /** Feature flags */
    features?: FeaturesConfig;
    /** Query cache configuration (defaults: 5min staleTime, refetch on focus/reconnect) */
    query?: QueryConfig;
    /**
     * Server-side rendering (Next adapter). **Defaults to `true`** — generated page
     * wrappers render directly and the provider tree renders on the server, so page
     * content is present in the initial HTML (real, crawlable SSR). Set to `false`
     * to opt OUT and restore the legacy client-only render (content appears only
     * after hydration). The provider tree is store-driven, so SSR routes render
     * dynamically at request time.
     */
    ssr?: boolean;
}
/**
 * Custom store configuration for app-specific stores
 *
 * Allows apps to register custom Zustand stores with the framework's
 * store initialization system. Custom stores benefit from:
 * - Shell loader integration (critical stores block render)
 * - Retry logic and error handling
 * - Unified initialization flow
 *
 * @example
 * ```typescript
 * const customStores: CustomStoreConfig[] = [{
 *   name: 'dndop',
 *   type: 'critical',
 *   store: useDndopStore,
 * }];
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CustomStoreConfig {
    /** Store name for logging and debugging */
    name: string;
    /**
     * Store initialization priority
     * - 'critical': Blocks render until ready, shell loader stays visible
     * - 'regular': Initializes in background after critical stores
     */
    type: 'critical' | 'regular';
    /**
     * Zustand store reference (hook)
     * Can be called as a hook with a selector: `store((state) => state.isReady)`
     * Also has a .getState() method for direct state access
     */
    store: {
        (selector: (state: any) => any): any;
        getState: () => {
            initialize?: () => Promise<boolean | void>;
            [key: string]: any;
        };
        subscribe: (listener: () => void) => () => void;
    };
}
/**
 * AppProviders props interface with slot-based layout customization
 */
/**
 * Application providers props
 *
 * Clean, minimal API for configuring application providers with smart defaults.
 *
 * @example
 * ```typescript
 * // Minimal configuration
 * <ViteAppProviders
 *   config={{ app: { name: 'My App' } }}
 * />
 *
 * // Full configuration
 * <ViteAppProviders
 *   config={{
 *     app: { name: 'My App' },
 *     auth: { authRoute: '/signin' },
 *     seo: {},
 *     layout: { preset: 'landing' },
 *     features: { debug: true }
 *   }}
 *   layout={{
 *     header: { end: () => <LoginButton /> },
 *     footer: () => <CustomFooter />
 *   }}
 * />
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AppProvidersProps {
    /**
     * Consolidated application configuration
     *
     * All configuration is optional with smart defaults.
     * Pass only what you need to override.
     */
    config?: AppConfig;
    /**
     * Layout configuration - simple API for customizing layout
     *
     * @example
     * ```typescript
     * // Preset only
     * layout={{ preset: 'admin' }}
     *
     * // Slot override
     * layout={{ header: { end: () => <MyButton /> } }}
     *
     * // Full override
     * layout={{ header: () => <CustomHeader /> }}
     * ```
     */
    layout?: LayoutConfig;
    /**
     * Child components
     *
     * Custom routing content. When provided, overrides framework routing.
     */
    children?: ReactNode;
    /**
     * Custom store configurations
     *
     * Register Zustand stores to benefit from shell loader, retry logic,
     * error handling. Critical stores block render.
     *
     * @example
     * ```typescript
     * customStores={[{
     *   name: 'dndop',
     *   type: 'critical',
     *   store: useDndopStore,
     * }]}
     * ```
     */
    customStores?: CustomStoreConfig[];
}
/**
 * Resolved layout configuration interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ResolvedLayoutConfig {
    /** Current preset name */
    preset: LayoutPreset;
    /** Resolved app configuration */
    app: {
        name: string;
        metadata: Record<string, any>;
    };
}

/**
 * @fileoverview DoNotDev Framework - Unified Types & Constants
 * @description Single source of truth for all framework types and constants
 * @package @donotdev/types
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 *
 * @remarks
 * This file consolidates all framework types and constants to prevent unnecessary splitting
 * and ensure DRY principles. All magic strings are replaced with typed constants.
 */

/**
 * Supported platform identifiers
 * @constant
 */
declare const PLATFORMS: {
    readonly VITE: "vite";
    readonly NEXTJS: "nextjs";
    readonly EXPO: "expo";
    readonly REACT_NATIVE: "react-native";
    readonly UNKNOWN: "unknown";
};
/**
 * Platform type derived from PLATFORMS constant
 */
type Platform = (typeof PLATFORMS)[keyof typeof PLATFORMS];
/**
 * Supported environment modes
 * @constant
 */
declare const ENVIRONMENTS: {
    readonly DEVELOPMENT: "development";
    readonly PRODUCTION: "production";
    readonly TEST: "test";
};
/**
 * Environment mode type derived from ENVIRONMENTS constant
 */
type EnvironmentMode = (typeof ENVIRONMENTS)[keyof typeof ENVIRONMENTS];
/**
 * Supported execution contexts
 * @constant
 */
declare const CONTEXTS: {
    readonly CLIENT: "client";
    readonly SERVER: "server";
    readonly BUILD: "build";
};
/**
 * Context type derived from CONTEXTS constant
 */
type Context = (typeof CONTEXTS)[keyof typeof CONTEXTS];
/**
 * Platform detection confidence thresholds
 * @constant
 */
declare const CONFIDENCE_LEVELS: {
    readonly HIGH: 0.95;
    readonly MEDIUM: 0.8;
    readonly LOW: 0.7;
    readonly MINIMUM: 0.3;
};
/**
 * Confidence level type derived from CONFIDENCE_LEVELS constant
 */
type ConfidenceLevel = (typeof CONFIDENCE_LEVELS)[keyof typeof CONFIDENCE_LEVELS];
/**
 * Unified feature status for all feature packages
 * Replaces combinatorial boolean flags (initialized, authStateChecked, loading) with single-source-of-truth enum.
 *
 * **Status values:**
 * - `initializing`: Feature is loading/initializing (show skeleton/loader, DON'T redirect yet)
 * - `ready`: Feature fully operational (check user state, redirect if needed)
 * - `degraded`: Feature unavailable but app continues (protected routes redirect with error, public routes allow access)
 * - `error`: Feature encountered recoverable error (protected routes redirect with error)
 *
 * **Usage in guards:**
 * - Protected routes with `degraded` status redirect to auth route with `?error=auth_unavailable`
 * - Protected routes with `error` status redirect to auth route with `?error=auth_error`
 * - `initializing` shows loader, doesn't redirect
 * - `ready` performs normal auth checks
 *
 * @example
 * ```typescript
 * switch (status) {
 *   case FEATURE_STATUS.INITIALIZING: return <Skeleton />;
 *   case FEATURE_STATUS.DEGRADED:
 *     // Protected route → redirect with error
 *     // Public route → allow access
 *     return authRequired ? <Redirect to="/auth?error=auth_unavailable" /> : children;
 *   case FEATURE_STATUS.READY: return user ? children : <Redirect />;
 *   case FEATURE_STATUS.ERROR: return <ErrorBoundary />;
 * }
 * ```
 */
declare const FEATURE_STATUS: {
    readonly INITIALIZING: "initializing";
    readonly READY: "ready";
    readonly DEGRADED: "degraded";
    readonly ERROR: "error";
};
/**
 * Feature status type derived from FEATURE_STATUS constant
 */
type FeatureStatus = (typeof FEATURE_STATUS)[keyof typeof FEATURE_STATUS];
/**
 * Supported storage backend types
 * @constant
 */
declare const STORAGE_TYPES: {
    readonly LOCAL: "localStorage";
    readonly SESSION: "sessionStorage";
    readonly INDEXED_DB: "indexedDB";
    readonly MEMORY: "memory";
};
/**
 * Storage type derived from STORAGE_TYPES constant
 */
type StorageType = (typeof STORAGE_TYPES)[keyof typeof STORAGE_TYPES];
/**
 * Storage scope levels for data isolation
 * @constant
 */
declare const STORAGE_SCOPES: {
    readonly USER: "user";
    readonly GLOBAL: "global";
    readonly SESSION: "session";
};
/**
 * Storage scope type derived from STORAGE_SCOPES constant
 */
type StorageScope = (typeof STORAGE_SCOPES)[keyof typeof STORAGE_SCOPES];
/**
 * PWA display modes
 * @constant
 */
declare const PWA_DISPLAY_MODES: {
    readonly STANDALONE: "standalone";
    readonly FULLSCREEN: "fullscreen";
    readonly MINIMAL_UI: "minimal-ui";
    readonly BROWSER: "browser";
};
/**
 * PWA display mode type derived from PWA_DISPLAY_MODES constant
 */
type PWADisplayMode = (typeof PWA_DISPLAY_MODES)[keyof typeof PWA_DISPLAY_MODES];
/**
 * PWA asset types
 * @constant
 */
declare const PWA_ASSET_TYPES: {
    readonly MANIFEST: "manifest";
    readonly SERVICE_WORKER: "service-worker";
    readonly ICON: "icon";
};
/**
 * PWA asset type derived from PWA_ASSET_TYPES constant
 */
type PWAAssetType = (typeof PWA_ASSET_TYPES)[keyof typeof PWA_ASSET_TYPES];
/**
 * Route discovery sources
 * @constant
 */
declare const ROUTE_SOURCES: {
    readonly AUTO: "auto-discovery";
    readonly MANUAL: "manual";
    readonly HYBRID: "hybrid";
};
/**
 * Route source type derived from ROUTE_SOURCES constant
 */
type RouteSource = (typeof ROUTE_SOURCES)[keyof typeof ROUTE_SOURCES];
/**
 * Generic ID type used throughout the application
 * @description Currently a string, but typed for future flexibility
 */
type ID = string;
/**
 * Generic timestamp format for dates and times
 * @description ISO 8601 string format (e.g., "2025-01-15T10:30:00.000Z")
 */
type Timestamp = string;
/**
 * Generic pagination options for fetching paginated data
 */
interface PaginationOptions {
    /** The page number (1-indexed) */
    page: number;
    /** The number of items per page */
    pageSize: number;
}
/**
 * Generic API response format for consistent error handling
 * @template T - The type of data in the response
 */
interface ApiResponse<T> {
    /** Indicates whether the operation was successful */
    success: boolean;
    /** The data returned by the operation (if successful) */
    data?: T;
    /** Error information (if the operation failed) */
    error?: {
        /** A machine-readable error code */
        code: string;
        /** A human-readable error message */
        message: string;
    };
}
/**
 * Basic user information that can be shared in various contexts
 */
interface BasicUserInfo {
    /** The unique identifier for the user */
    id: ID;
    /** The user's display name (if available) */
    displayName?: string | null;
    /** The user's email address (if available) */
    email?: string | null;
    /** The URL of the user's profile photo (if available) */
    photoURL?: string | null;
}
/**
 * Basic document with ID and timestamps
 * @description All entity documents in the system should extend this interface
 */
interface BaseDocument {
    /** The unique identifier for the document */
    id: ID;
    /** When the document was created */
    createdAt: Timestamp;
    /** When the document was last updated */
    updatedAt: Timestamp;
    /** The ID of the user who created the document (if available) */
    createdById?: ID;
    /** The ID of the user who last updated the document (if available) */
    updatedById?: ID;
}
/**
 * Page-level authentication requirements
 * @description Used in PageMeta and NavigationRoute for route-level auth
 */
type PageAuth = boolean | {
    /** Whether authentication is required */
    required?: boolean;
    /** Required user role */
    role?: UserRole;
    /** Required subscription tier */
    tier?: SubscriptionTier;
    /** Custom validation function */
    validate?: (role: string, tier: string) => boolean;
};
/**
 * Page metadata interface for route discovery and configuration
 *
 * @remarks
 * **ALL PROPERTIES ARE OPTIONAL** - Framework provides smart defaults:
 *
 * - `auth`: false (public) by default - YOU must specify auth requirements explicitly
 * - `title`: Auto-extracted from filename (ShowcasePage → "Showcase")
 * - `entity`: Auto-extracted from path (pages/showcase/ → "showcase")
 * - `action`: Auto-extracted from filename patterns (ListPage → "list", FormPage → "form")
 * - `route`: Only needed for custom paths or dynamic routes like :id, :slug
 *
 * @example Simple page (no meta needed):
 * ```tsx
 * export function HomePage() {
 *   return <PageContainer>...</PageContainer>;
 * }
 * // Framework provides: auth=false, title from home.title, entity=home
 * ```
 *
 * @example Dynamic route (string format - explicit path):
 * ```tsx
 * export const meta: PageMeta = {
 *   route: '/blog/:slug'  // Creates /blog/:slug
 * };
 * // Framework provides: auth=false, title from blog.title, entity=blog
 * ```
 *
 * @example Dynamic route (object format - auto-generates base path):
 * ```tsx
 * export const meta: PageMeta = {
 *   route: { params: ['id'] }  // Creates /myRoute/:id (base path from file location)
 * };
 * // For file at pages/myRoute/DetailPage.tsx → route becomes /myRoute/:id
 * ```
 *
 * @example Auth-required (developer must be explicit):
 * ```tsx
 * export const meta: PageMeta = {
 *   auth: { required: true }  // YOU decide what needs auth
 * };
 * ```
 */
/**
 * SEO metadata for a page
 * @description Controls `<title>`, meta description, Open Graph, and Twitter Cards.
 * All fields default to i18n lookup when undefined.
 *
 * @example i18n-first (default)
 * ```tsx
 * export const meta: PageMeta = {
 *   namespace: 'pricing',  // Uses pricing:title, pricing:description
 * };
 * ```
 *
 * @example Full title control (escape "Page | App" format)
 * ```tsx
 * export const meta: PageMeta = {
 *   namespace: 'home',
 *   seo: { fullTitle: 'DoNotDev - Build Apps in Minutes' },
 * };
 * ```
 *
 * @example siteName only
 * ```tsx
 * export const meta: PageMeta = {
 *   seo: { title: null },  // → "AppName"
 * };
 * ```
 *
 * @version 0.2.0
 * @since 0.2.0
 * @author AMBROISE PARK Consulting
 */
interface SeoMeta {
    /**
     * Page title segment (appears as "title | siteName")
     * @description
     * - `undefined` → i18n lookup (`ns:title`)
     * - `string` → literal value + siteName suffix
     * - `null` → siteName only (no page title)
     */
    title?: string | null;
    /**
     * Full title override (no suffix appended)
     * @description Escapes the "Page | App" format entirely.
     * Takes priority over `title` when set.
     */
    fullTitle?: string;
    /**
     * Meta description
     * @description
     * - `undefined` → i18n lookup (`ns:description`)
     * - `string` → literal value
     * - `null` → omit meta description
     */
    description?: string | null;
    /** Open Graph image URL (relative or absolute) */
    image?: string;
    /** Keywords for meta tag */
    keywords?: string[];
    /** Page type for Open Graph */
    type?: 'website' | 'article' | 'product';
    /** Exclude from search engine indexing */
    noindex?: boolean;
}
/** Page-level metadata for route discovery, auth, SEO, and navigation. */
interface PageMeta {
    /** Authentication requirements for this route */
    auth?: PageAuth;
    /** Route configuration - just define the exact path you want */
    route?: string | {
        params?: string[];
    };
    /** Page title (optional - framework auto-extracts from filename if not provided) */
    title?: string;
    /**
     * Translation/SEO namespace for this page
     * @description Used for meta tags and translations
     */
    namespace?: string;
    /**
     * Icon for navigation (optional - framework provides smart defaults)
     * @description **ONLY lucide-react JSX components** - extracted as component name string at build time for tree-shaking.
     *
     * **RESTRICTIONS:**
     * - ✅ Only: `<Rocket />`, `<ShoppingCart />`, `<Home />` (lucide-react JSX components)
     * - ❌ NOT: Emojis (`"🚀"`), strings (`"Rocket"`), or custom ReactNode
     *
     * **Why?** This is for build-time extraction and tree-shaking. The component name is extracted and stored as a string.
     *
     * **For flexible icons** (emojis, strings, custom components), use the `Icon` component directly in your JSX, not in PageMeta.
     *
     * @example
     * ```tsx
     * import { Rocket } from 'lucide-react';
     * export const meta: PageMeta = {
     *   icon: <Rocket />  // ✅ Correct - lucide-react component
     * };
     * ```
     *
     * @example
     * ```tsx
     * // ❌ WRONG - Don't use emojis or strings in PageMeta
     * export const meta: PageMeta = {
     *   icon: "🚀"  // ❌ Not supported in PageMeta
     * };
     * ```
     */
    icon?: ReactNode;
    /**
     * Hide from navigation menu (default: false - shows in navigation)
     * @description Set to true to exclude this route from navigation menus
     * @default false
     * @example
     * ```tsx
     * export const meta: PageMeta = {
     *   hideFromMenu: true // Won't appear in HeaderNavigation, Sidebar, etc.
     * };
     * ```
     */
    hideFromMenu?: boolean;
    /**
     * Hide breadcrumbs on this page (default: false)
     * @description Set to true to hide framework breadcrumbs on this route
     * @default false
     */
    hideBreadcrumbs?: boolean;
    /**
     * Layout preset override for this route
     * @description When set, overrides the app's default layout preset for this route only.
     * When absent, the app's `appConfig.preset` is used.
     * The override is transient — navigating away restores the next route's preset or the app default.
     *
     * @example
     * ```tsx
     * export const meta: PageMeta = {
     *   preset: 'admin', // This route uses admin layout (sidebar, compact density)
     *   auth: true,
     * };
     * ```
     */
    preset?: LayoutPreset;
    /**
     * SEO metadata override
     * @description Fine-grained control over `<title>`, meta description, and Open Graph tags.
     * When omitted, SEO uses i18n lookup based on `namespace` (i18n-first by default).
     *
     * @example Escape "Page | App" format
     * ```tsx
     * export const meta: PageMeta = {
     *   namespace: 'home',
     *   seo: { fullTitle: 'DoNotDev - Build Apps in Minutes' },
     * };
     * ```
     *
     * @example siteName only (no page title)
     * ```tsx
     * export const meta: PageMeta = {
     *   seo: { title: null },
     * };
     * ```
     */
    seo?: SeoMeta;
    /**
     * User-facing category for sidebar/menu grouping
     * @description Groups routes into collapsible sections in navigation. Unlike
     * auto-discovered `entity` (parent-dir name), `category` is author-declared
     * and typically maps to a higher-level folder (e.g., `Analyzers`, `Tools`).
     * Routes without `category` render ungrouped at the top of the menu.
     *
     * @example
     * ```tsx
     * export const meta: PageMeta = {
     *   namespace: 'budgetPlanner',
     *   category: 'Analyzers',
     *   icon: <WalletIcon />,
     * };
     * ```
     */
    category?: string;
}
/**
 * Route metadata (discovery-generated)
 * @description Complete route metadata including auto-discovered fields from RouteDiscovery
 *
 * This extends PageMeta with fields that are automatically discovered from file paths:
 * - `entity`: Auto-extracted from path (pages/showcase/ → "showcase")
 * - `action`: Auto-extracted from filename patterns (ListPage → "list", FormPage → "form")
 *
 * These fields are always present in discovered routes but cannot be set in PageMeta.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RouteMeta extends PageMeta {
    /** Entity/domain grouping - auto-discovered from file path (not user-configurable) */
    entity?: string;
    /** Action type for route categorization - auto-discovered from filename patterns (not user-configurable) */
    action?: string | null;
    /** File path where route was discovered */
    file?: string;
}
/**
 * Navigation route interface
 * @description Single source of truth for all navigation routes
 */
interface NavigationRoute {
    /** Route path */
    path: string;
    /** Display label for navigation */
    label: string;
    /** Optional icon identifier or component */
    icon?: string | ReactNode;
    /** Whether route is external */
    external?: boolean;
    /** Whether route is disabled */
    disabled?: boolean;
    /** Badge content for notifications */
    badge?: string | number;
    /** Authentication configuration */
    auth?: PageAuth;
    /** Route metadata (includes auto-discovered fields) */
    meta?: RouteMeta;
    /** Nested child routes */
    children?: NavigationRoute[];
}
/**
 * Storage options for get/set operations
 */
interface StorageOptions {
    /**
     * Whether to encrypt the data
     * @default false for most data, true for sensitive data
     */
    encryption?: boolean;
    /**
     * Time in seconds after which the data expires
     * @description Set to 0 for no expiration
     * @default 0
     */
    expiry?: number;
    /**
     * Storage scope for data isolation
     * @description
     * - 'user': User-specific data, tied to user ID (requires auth)
     * - 'global': Application-wide data, not tied to specific user
     * - 'session': Session-only data, cleared on logout/browser close
     * @default 'user'
     */
    scope?: StorageScope;
}
/**
 * Storage manager interface
 * @description Main interface for all storage operations
 */
interface IStorageManager {
    /**
     * Retrieve data from storage
     * @param key - Storage key
     * @param options - Storage options
     * @returns Promise resolving to the stored data or null if not found
     */
    get<T>(key: string, options?: StorageOptions): Promise<T | null>;
    /**
     * Store data
     * @param key - Storage key
     * @param value - Data to store
     * @param options - Storage options
     * @returns Promise resolving when data is stored
     */
    set<T>(key: string, value: T, options?: StorageOptions): Promise<void>;
    /**
     * Remove data from storage
     * @param key - Storage key
     * @returns Promise resolving when data is removed
     */
    remove(key: string): Promise<void>;
    /**
     * Clear all data in the specified scope
     * @param scope - Scope to clear, or all scopes if not specified
     * @returns Promise resolving when data is cleared
     */
    clear(scope?: StorageScope): Promise<void>;
    /**
     * Store sensitive data with encryption
     * @description Shorthand for set() with encryption=true
     * @param key - Storage key
     * @param value - Data to store
     * @param options - Storage options (encryption will be set to true)
     * @returns Promise resolving when data is stored
     */
    setSecure<T>(key: string, value: T, options?: Omit<StorageOptions, 'encryption'>): Promise<void>;
    /**
     * Retrieve sensitive data with decryption
     * @description Shorthand for get() with encryption=true
     * @param key - Storage key
     * @param options - Storage options (encryption will be set to true)
     * @returns Promise resolving to the decrypted data or null if not found
     */
    getSecure<T>(key: string, options?: Omit<StorageOptions, 'encryption'>): Promise<T | null>;
}
/**
 * Storage strategy interface
 * @description Used by StorageManager to delegate storage operations
 */
interface IStorageStrategy {
    /**
     * Retrieve data from storage
     * @param key - Storage key
     * @param options - Storage options
     * @returns Promise resolving to the stored data or null if not found
     */
    get<T>(key: string, options?: StorageOptions): Promise<T | null>;
    /**
     * Store data
     * @param key - Storage key
     * @param value - Data to store
     * @param options - Storage options
     * @returns Promise resolving when data is stored
     */
    set<T>(key: string, value: T, options?: StorageOptions): Promise<void>;
    /**
     * Remove data from storage
     * @param key - Storage key
     * @returns Promise resolving when data is removed
     */
    remove(key: string): Promise<void>;
    /**
     * Clear all data in the specified scope
     * @param scope - Scope to clear, or all scopes if not specified
     * @returns Promise resolving when data is cleared
     */
    clear(scope?: StorageScope): Promise<void>;
}
/**
 * i18n Plugin Configuration
 * @description Configuration for internationalization system
 */
interface I18nPluginConfig {
    /** Mapping of language → namespace → loader function */
    mapping: Record<string, Record<string, () => Promise<any>>>;
    /** List of available language codes */
    languages: string[];
    /** List of eagerly loaded namespace identifiers */
    eager: string[];
    /** Fallback language code */
    fallback: string;
    /** Preloaded translation content for eager namespaces (optional) */
    content?: Record<string, Record<string, any>>;
    /** Lazy loader functions — static import() calls generated by Vite plugin (optional, not serializable) */
    loaders?: Record<string, Record<string, () => Promise<any>>>;
    /** Storage configuration */
    storage: {
        /** Storage backend type */
        type: StorageType;
        /** Storage key prefix */
        prefix: string;
        /** Time-to-live in seconds */
        ttl: number;
        /** Whether to encrypt stored data */
        encryption: boolean;
        /** Maximum storage size in bytes */
        maxSize: number;
    };
    /** Performance configuration */
    performance: {
        /** Maximum cache size */
        cacheSize: number;
        /** Error cache TTL in seconds */
        errorCacheTTL: number;
    };
    /** Discovery manifest metadata */
    manifest: {
        /** Total number of translation files */
        totalFiles: number;
        /** Total number of namespaces */
        totalNamespaces: number;
        /** Total number of languages */
        totalLanguages: number;
        /** Number of eagerly loaded namespaces */
        eagerNamespaces: number;
        /** ISO timestamp of generation */
        generatedAt: string;
    };
    /** Whether debug mode is enabled */
    debug: boolean;
}
/**
 * Routes Plugin Configuration
 * @description Complete route configuration populated by discovery system
 */
interface RoutesPluginConfig {
    /**
     * Array of discovered routes
     * @description All routes discovered by the route discovery system
     */
    mapping: Array<{
        /**
         * URL path for the route (platform-agnostic)
         * @description The URL path that users see in their browser
         * @example '/showcase/layouts', '/users/:id', '/dashboard'
         */
        path: string;
        /**
         * Lazy component reference (Vite-specific)
         * @description React.lazy() component for code splitting
         * @example lazy(() => import("/src/pages/showcase/LayoutsPage"))
         */
        component: any;
        /**
         * Absolute file system path (Next.js-specific)
         * @description The absolute path to the component file
         * @example '/src/pages/showcase/LayoutsPage.tsx'
         */
        importPath: string;
        /**
         * Export name for named exports
         * @example 'HomePage', 'AboutPage'
         */
        exportName?: string;
        /**
         * Authentication configuration (platform-agnostic)
         * @description Defines whether the route requires authentication
         */
        auth: PageAuth;
        /**
         * Route metadata (platform-agnostic)
         * @description Additional information about the route, including auto-discovered fields
         */
        meta: RouteMeta;
    }>;
    /**
     * Discovery metadata and statistics
     * @description Information about the route discovery process
     */
    manifest: {
        /** Total number of discovered routes */
        totalRoutes: number;
        /** Number of routes requiring authentication */
        authRequired: number;
        /** Number of public routes */
        publicRoutes: number;
        /** Source of routes (auto-discovery vs manual) */
        source: RouteSource;
        /** ISO timestamp when routes were generated */
        generatedAt: string;
    };
}
/**
 * Themes Plugin Configuration
 * @description Configuration for theme discovery and management
 */
interface ThemesPluginConfig {
    /** Mapping of theme names to theme configurations */
    mapping: Record<string, any>;
    /** Array of discovered themes */
    discovered: Array<{
        /** Theme identifier */
        name: string;
        /** Human-readable theme name */
        displayName: string;
        /** Whether this is a dark theme */
        isDark: boolean;
        /** Theme metadata */
        meta: {
            /** Icon identifier */
            icon: string;
            /** Theme description */
            description?: string;
            /** Theme category */
            category?: string;
            /** Theme author */
            author?: string;
            /** Additional metadata */
            [key: string]: any;
        };
        /** Source file path */
        source: string;
        /** Whether theme is essential (cannot be disabled) */
        essential: boolean;
    }>;
    /** CSS custom property variables */
    variables: Record<string, string>;
    /** Utility class mappings */
    utilities: Record<string, Record<string, string>>;
    /** Discovery manifest metadata */
    manifest: {
        /** Total number of discovered themes */
        totalThemes: number;
        /** Total number of CSS variables */
        totalVariables: number;
        /** Total number of utility classes */
        totalUtilities: number;
        /** ISO timestamp of generation */
        generatedAt: string;
    };
}
/**
 * Assets Plugin Configuration
 * @description Configuration for static asset management
 */
interface AssetsPluginConfig {
    /** Mapping of asset paths to asset metadata */
    mapping: Record<string, any>;
    /** SVG content of logo.svg for inline rendering with CSS variable theming */
    logoSvgContent?: string | null;
    /** Discovery manifest metadata */
    manifest: {
        /** Total number of discovered assets */
        totalAssets: number;
        /** ISO timestamp of generation */
        generatedAt: string;
    };
}
/**
 * PWA Plugin Configuration
 * @description Configuration for Progressive Web App features
 */
interface PWAPluginConfig {
    /** Array of PWA assets */
    assets: Array<{
        /** Type of PWA asset */
        type: PWAAssetType;
        /** Asset file path */
        path: string;
        /** Asset file size in bytes */
        size?: number;
        /** Asset content (for inline assets) */
        content?: any;
        /** Asset format (for images) */
        format?: string;
        /** Asset purpose (for icons) */
        purpose?: string;
    }>;
    /** PWA manifest configuration */
    manifest: {
        /** Application name */
        name: string;
        /** Short application name */
        short_name: string;
        /** Application description */
        description: string;
        /** Start URL */
        start_url: string;
        /** Display mode */
        display: PWADisplayMode;
        /** Background color */
        background_color: string;
        /** Theme color */
        theme_color: string;
        /** Array of app icons */
        icons: Array<{
            /** Icon source path */
            src: string;
            /** Icon sizes (e.g., '192x192') */
            sizes: string;
            /** Icon MIME type */
            type: string;
            /** Icon purpose (e.g., 'any', 'maskable') */
            purpose: string;
        }>;
    };
    /** Discovery manifest metadata */
    manifestInfo: {
        /** Total number of PWA assets */
        totalAssets: number;
        /** Total number of icons */
        totalIcons: number;
        /** Whether service worker is present */
        hasServiceWorker: boolean;
        /** ISO timestamp of generation */
        generatedAt: string;
    };
}
/**
 * Features Plugin Configuration
 * @description Configuration for feature discovery and enablement
 *
 * @remarks
 * This interface defines the structure for feature discovery data that is populated
 * at build time and made available at runtime for feature availability checking.
 *
 * @example
 * ```typescript
 * // Generated by feature discovery system
 * const featuresConfig: FeaturesPluginConfig = {
 *   available: ['auth', 'billing', 'i18n', 'oauth'],
 *   enabled: ['auth', 'i18n'],
 *   overridden: false
 * };
 * ```
 */
interface FeaturesPluginConfig {
    /**
     * List of all available features discovered in packages/features/
     * @example ['auth', 'billing', 'i18n', 'oauth']
     */
    available: string[];
}
/**
 * Complete DoNotDev framework configuration structure
 * @description Single source of truth for all framework configuration
 *
 * @remarks
 * All discovery plugins add their data to this unified config.
 * Available at runtime via globalThis._DNDEV_CONFIG_ or window._DNDEV_CONFIG_
 */
interface DndevFrameworkConfig {
    /** Framework platform (Vite or Next.js) */
    platform: Platform;
    /** Current environment mode */
    mode: EnvironmentMode;
    /** Framework version */
    version: string;
    /** Execution context */
    context: Context;
    /** Unix timestamp of config generation */
    timestamp: number;
    /** i18n plugin configuration (optional) */
    i18n?: I18nPluginConfig;
    /** Routes plugin configuration (optional) */
    routes?: RoutesPluginConfig;
    /** Themes plugin configuration (optional) */
    themes?: ThemesPluginConfig;
    /** Assets plugin configuration (optional) */
    assets?: AssetsPluginConfig;
    /** PWA plugin configuration (optional) */
    pwa?: PWAPluginConfig;
    /** Features plugin configuration (optional) */
    features?: FeaturesPluginConfig;
    /** Environment variables (VITE_* variables from .env files) */
    env?: Record<string, string>;
}

/**
 * @fileoverview Billing Constants
 * @description Constants for billing domain. Defines subscription status values, Stripe modes, and billing-related constants.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Standard subscription status values from billing providers
 * Apps can override these by providing their own status constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const SUBSCRIPTION_STATUS: {
    readonly ACTIVE: "active";
    readonly CANCELED: "canceled";
    readonly INCOMPLETE: "incomplete";
    readonly INCOMPLETE_EXPIRED: "incomplete_expired";
    readonly PAST_DUE: "past_due";
    readonly TRIALING: "trialing";
    readonly UNPAID: "unpaid";
};
/**
 * Override subscription status for custom app needs
 * @example
 * ```typescript
 * // In your app's config
 * overrideSubscriptionStatus({
 *   ACTIVE: 'subscribed',
 *   CANCELED: 'cancelled',
 *   TRIALING: 'trial'
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function overrideSubscriptionStatus(customStatus: Partial<typeof SUBSCRIPTION_STATUS>): void;
/**
 * Type for subscription status names
 * Apps can extend this with their own custom statuses
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type SubscriptionStatus = (typeof SUBSCRIPTION_STATUS)[keyof typeof SUBSCRIPTION_STATUS] | string;
/**
 * Standard payment mode values for Stripe checkout
 * Apps can override these by providing their own mode constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const STRIPE_MODES: {
    readonly PAYMENT: "payment";
    readonly SUBSCRIPTION: "subscription";
};
/**
 * Override payment modes for custom app needs
 * @example
 * ```typescript
 * // In your app's config
 * overridePaymentModes({
 *   PAYMENT: 'one_time',
 *   SUBSCRIPTION: 'recurring'
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function overridePaymentModes(customModes: Partial<typeof STRIPE_MODES>): void;
/**
 * Type for payment mode names
 * Apps can extend this with their own custom modes
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PaymentMode = (typeof STRIPE_MODES)[keyof typeof STRIPE_MODES] | string;
/**
 * Standard subscription duration values
 * Apps can override these by providing their own duration constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const SUBSCRIPTION_DURATIONS: {
    readonly ONE_MONTH: "1month";
    readonly THREE_MONTHS: "3months";
    readonly SIX_MONTHS: "6months";
    readonly ONE_YEAR: "1year";
    readonly TWO_YEARS: "2years";
    readonly LIFETIME: "lifetime";
};
/**
 * Type for subscription duration names
 * Apps can extend this with their own custom durations
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type SubscriptionDuration = (typeof SUBSCRIPTION_DURATIONS)[keyof typeof SUBSCRIPTION_DURATIONS] | string;
/**
 * Common subscription features that apps can reference
 * Apps can use these or define their own custom features
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CommonSubscriptionFeatures = 'basic-usage' | 'limited-storage' | 'standard-support' | 'cloud-sync' | 'advanced-analytics' | 'priority-support' | 'custom-branding' | 'team-collaboration' | 'ai-assistant' | 'custom-models' | 'unlimited-generations' | 'advanced-integrations';
/**
 * Subscription claims stored in Firebase Auth custom claims
 * Type definition - schema in schemas.ts validates against this structure
 */
type SubscriptionClaims = {
    tier: string;
    subscriptionId: string | null;
    customerId: string;
    status: SubscriptionStatus;
    subscriptionEnd: string | null;
    cancelAtPeriodEnd: boolean;
    updatedAt: string;
    isDefault?: boolean;
};
/**
 * Factory function to create default subscription claims
 * @param userId - User ID for the subscription
 * @returns Default subscription claims for free tier
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function createDefaultSubscriptionClaims(userId: string): SubscriptionClaims;
/**
 * Generic subscription configuration interface
 * Apps define their specific subscription tiers and features
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SubscriptionConfig {
    /** Subscription tiers with their features and hierarchy */
    tiers: Record<string, {
        /** Features available for this tier */
        features: string[];
        /** Tier level for comparison (higher = more access) */
        level: number;
    }>;
}
/**
 * Common tier configurations that apps can use as a starting point
 * Apps can extend this or create their own completely custom configs
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const COMMON_TIER_CONFIGS: {
    free: {
        features: string[];
        level: number;
    };
    pro: {
        features: string[];
        level: number;
    };
    ai: {
        features: string[];
        level: number;
    };
};
/**
 * Default subscription for new users (free tier)
 * Framework consumers can override these defaults
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const DEFAULT_SUBSCRIPTION: SubscriptionClaims;

/**
 * @fileoverview Schema Definitions for Billing and Subscription Management
 * @description Single source of truth for all billing-related data validation. Defines Valibot schemas for billing, subscriptions, checkout sessions, and related data structures.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Schema for creating a checkout session request
 * Uses constants for enum values to ensure consistency
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const CreateCheckoutSessionRequestSchema: v.SchemaWithPipe<readonly [v.ObjectSchema<{
    readonly userId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly productId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Stripe price ID (fixed pricing mode) */
    readonly priceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Amount in cents (dynamic pricing mode) */
    readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    /** Product name shown on Stripe checkout (dynamic pricing mode) */
    readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
    /** Currency code, defaults to 'eur' (dynamic pricing mode) */
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, undefined>;
    readonly successUrl: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
    readonly cancelUrl: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
    readonly customerEmail: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
    readonly userEmail: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly mode: v.OptionalSchema<v.PicklistSchema<["payment", "subscription"], undefined>, undefined>;
}, undefined>, v.CheckAction<{
    userId?: string | undefined;
    productId?: string | undefined;
    priceId?: string | undefined;
    unitAmount?: number | undefined;
    productName?: string | undefined;
    currency?: string | undefined;
    successUrl: string;
    cancelUrl: string;
    customerEmail?: string | undefined;
    userEmail?: string | undefined;
    metadata?: {
        [x: string]: string;
    } | undefined;
    allowPromotionCodes?: boolean | undefined;
    mode?: "payment" | "subscription" | undefined;
}, "Either priceId or (unitAmount + productName) is required">]>;
/**
 * Schema for creating a checkout session response
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const CreateCheckoutSessionResponseSchema: v.ObjectSchema<{
    readonly sessionId: v.StringSchema<undefined>;
    readonly sessionUrl: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>;
}, undefined>;
/**
 * Schema for subscription data from billing providers
 * Uses constants for enum values to ensure consistency
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const SubscriptionDataSchema: v.ObjectSchema<{
    readonly userId: v.StringSchema<undefined>;
    readonly tier: v.StringSchema<undefined>;
    readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
    readonly customerId: v.StringSchema<undefined>;
    readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
    readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
    readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
}, undefined>;
/**
 * Schema for subscription claims stored in Firebase Auth custom claims
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const SubscriptionClaimsSchema: v.ObjectSchema<{
    readonly tier: v.StringSchema<undefined>;
    readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
    readonly customerId: v.StringSchema<undefined>;
    readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
    readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
    readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
    readonly isDefault: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
}, undefined>;
/**
 * Schema for webhook event data
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const WebhookEventSchema: v.ObjectSchema<{
    readonly id: v.StringSchema<undefined>;
    readonly type: v.StringSchema<undefined>;
    readonly data: v.ObjectSchema<{
        readonly object: v.AnySchema;
    }, undefined>;
    readonly created: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
}, undefined>;
/**
 * Schema for Stripe checkout session metadata
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const CheckoutSessionMetadataSchema: v.LooseObjectSchema<{
    readonly userId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly firebaseUid: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly productType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/**
 * Create checkout session request type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CreateCheckoutSessionRequest = v.InferOutput<typeof CreateCheckoutSessionRequestSchema>;
/**
 * Create checkout session response type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CreateCheckoutSessionResponse = v.InferOutput<typeof CreateCheckoutSessionResponseSchema>;
/**
 * Subscription data type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type SubscriptionData = v.InferOutput<typeof SubscriptionDataSchema>;
/**
 * Subscription claims type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Webhook event type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type WebhookEvent = v.InferOutput<typeof WebhookEventSchema>;
/**
 * Checkout session metadata type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CheckoutSessionMetadata = v.InferOutput<typeof CheckoutSessionMetadataSchema>;
/**
 * Stripe payment type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type StripePayment = v.InferOutput<typeof StripePaymentSchema> & {
    onPurchaseSuccess?: (userId: string, metadata: any) => Promise<void>;
    onPurchaseFailure?: (userId: string, metadata: any) => Promise<void>;
};
/**
 * Stripe subscription type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type StripeSubscription = v.InferOutput<typeof StripeSubscriptionSchema> & {
    onSubscriptionCreated?: (userId: string, metadata: any) => Promise<void>;
    onSubscriptionRenewed?: (userId: string, metadata: any) => Promise<void>;
    onSubscriptionCancelled?: (userId: string, metadata: any) => Promise<void>;
    onPaymentFailed?: (userId: string, metadata: any) => Promise<void>;
};
/**
 * Product declaration type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ProductDeclaration = v.InferOutput<typeof ProductDeclarationSchema> & {
    onPurchaseSuccess?: (userId: string, metadata: any) => Promise<void>;
    onPurchaseFailure?: (userId: string, metadata: any) => Promise<void>;
    onSubscriptionCreated?: (userId: string, metadata: any) => Promise<void>;
    onSubscriptionRenewed?: (userId: string, metadata: any) => Promise<void>;
    onSubscriptionCancelled?: (userId: string, metadata: any) => Promise<void>;
    onPaymentFailed?: (userId: string, metadata: any) => Promise<void>;
};
/**
 * Validate create checkout session request
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateCreateCheckoutSessionRequest(data: unknown): v.SafeParseResult<v.SchemaWithPipe<readonly [v.ObjectSchema<{
    readonly userId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly productId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Stripe price ID (fixed pricing mode) */
    readonly priceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Amount in cents (dynamic pricing mode) */
    readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    /** Product name shown on Stripe checkout (dynamic pricing mode) */
    readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
    /** Currency code, defaults to 'eur' (dynamic pricing mode) */
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, undefined>;
    readonly successUrl: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
    readonly cancelUrl: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
    readonly customerEmail: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
    readonly userEmail: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly mode: v.OptionalSchema<v.PicklistSchema<["payment", "subscription"], undefined>, undefined>;
}, undefined>, v.CheckAction<{
    userId?: string | undefined;
    productId?: string | undefined;
    priceId?: string | undefined;
    unitAmount?: number | undefined;
    productName?: string | undefined;
    currency?: string | undefined;
    successUrl: string;
    cancelUrl: string;
    customerEmail?: string | undefined;
    userEmail?: string | undefined;
    metadata?: {
        [x: string]: string;
    } | undefined;
    allowPromotionCodes?: boolean | undefined;
    mode?: "payment" | "subscription" | undefined;
}, "Either priceId or (unitAmount + productName) is required">]>>;
/**
 * Validate create checkout session response
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateCreateCheckoutSessionResponse(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly sessionId: v.StringSchema<undefined>;
    readonly sessionUrl: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>;
}, undefined>>;
/**
 * Validate subscription data
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateSubscriptionData(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly userId: v.StringSchema<undefined>;
    readonly tier: v.StringSchema<undefined>;
    readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
    readonly customerId: v.StringSchema<undefined>;
    readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
    readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
    readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
}, undefined>>;
/**
 * Validate subscription claims
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateSubscriptionClaims(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly tier: v.StringSchema<undefined>;
    readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
    readonly customerId: v.StringSchema<undefined>;
    readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
    readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
    readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
    readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
    readonly isDefault: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
}, undefined>>;
/**
 * Validate webhook event
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateWebhookEvent(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    readonly id: v.StringSchema<undefined>;
    readonly type: v.StringSchema<undefined>;
    readonly data: v.ObjectSchema<{
        readonly object: v.AnySchema;
    }, undefined>;
    readonly created: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
}, undefined>>;
/**
 * Validate checkout session metadata
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateCheckoutSessionMetadata(data: unknown): v.SafeParseResult<v.LooseObjectSchema<{
    readonly userId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly firebaseUid: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly productType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>>;
/**
 * Schema for one-time payment products
 * Core fields only - no assumptions about integrations
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const StripePaymentSchema: v.ObjectSchema<{
    readonly type: v.LiteralSchema<"StripePayment", undefined>;
    readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Product name is required">]>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, "EUR">;
    /** Stripe price ID (fixed pricing). Optional when using dynamic pricing. */
    readonly priceId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Stripe price ID is required">]>, undefined>;
    /** Default amount in cents (dynamic pricing). Used when no priceId. */
    readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    /** Product name for Stripe checkout (dynamic pricing). */
    readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
    /** Maximum allowed unit amount in cents. Security cap for client-provided amounts. */
    readonly maxUnitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly tier: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Tier is required">]>;
    readonly duration: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Duration is required">]>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>;
/**
 * Schema for recurring subscription products
 * Core fields only - no assumptions about integrations
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const StripeSubscriptionSchema: v.ObjectSchema<{
    readonly type: v.LiteralSchema<"StripeSubscription", undefined>;
    readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Product name is required">]>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, "EUR">;
    /** Stripe price ID. Required for subscriptions (price_data not supported for recurring). */
    readonly priceId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Stripe price ID is required">]>;
    readonly tier: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Tier is required">]>;
    readonly duration: v.PicklistSchema<["1month", "3months", "6months", "1year", "2years", "lifetime"], undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>;
/**
 * Union schema for all product types
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const ProductDeclarationSchema: v.VariantSchema<"type", [v.ObjectSchema<{
    readonly type: v.LiteralSchema<"StripePayment", undefined>;
    readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Product name is required">]>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, "EUR">;
    /** Stripe price ID (fixed pricing). Optional when using dynamic pricing. */
    readonly priceId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Stripe price ID is required">]>, undefined>;
    /** Default amount in cents (dynamic pricing). Used when no priceId. */
    readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    /** Product name for Stripe checkout (dynamic pricing). */
    readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
    /** Maximum allowed unit amount in cents. Security cap for client-provided amounts. */
    readonly maxUnitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly tier: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Tier is required">]>;
    readonly duration: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Duration is required">]>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>, v.ObjectSchema<{
    readonly type: v.LiteralSchema<"StripeSubscription", undefined>;
    readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Product name is required">]>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, "EUR">;
    /** Stripe price ID. Required for subscriptions (price_data not supported for recurring). */
    readonly priceId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Stripe price ID is required">]>;
    readonly tier: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Tier is required">]>;
    readonly duration: v.PicklistSchema<["1month", "3months", "6months", "1year", "2years", "lifetime"], undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>], undefined>;
/**
 * Schema for product declarations object
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const ProductDeclarationsSchema: v.RecordSchema<v.StringSchema<undefined>, v.VariantSchema<"type", [v.ObjectSchema<{
    readonly type: v.LiteralSchema<"StripePayment", undefined>;
    readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Product name is required">]>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, "EUR">;
    /** Stripe price ID (fixed pricing). Optional when using dynamic pricing. */
    readonly priceId: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Stripe price ID is required">]>, undefined>;
    /** Default amount in cents (dynamic pricing). Used when no priceId. */
    readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    /** Product name for Stripe checkout (dynamic pricing). */
    readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
    /** Maximum allowed unit amount in cents. Security cap for client-provided amounts. */
    readonly maxUnitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly tier: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Tier is required">]>;
    readonly duration: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Duration is required">]>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>, v.ObjectSchema<{
    readonly type: v.LiteralSchema<"StripeSubscription", undefined>;
    readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Product name is required">]>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, "EUR">;
    /** Stripe price ID. Required for subscriptions (price_data not supported for recurring). */
    readonly priceId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Stripe price ID is required">]>;
    readonly tier: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Tier is required">]>;
    readonly duration: v.PicklistSchema<["1month", "3months", "6months", "1year", "2years", "lifetime"], undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>], undefined>, undefined>;
/**
 * Schema for frontend billing configuration (display only)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const StripeFrontConfigSchema: v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
    readonly name: v.StringSchema<undefined>;
    readonly price: v.StringSchema<undefined>;
    readonly currency: v.StringSchema<undefined>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly features: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
    /** Stripe price ID (fixed pricing). Optional for dynamic pricing products. */
    readonly priceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Amount in cents (dynamic pricing). For display purposes. */
    readonly unitAmount: v.OptionalSchema<v.NumberSchema<undefined>, undefined>;
    /** Product name (dynamic pricing). For display purposes. */
    readonly productName: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
}, undefined>, undefined>;
/**
 * Schema for backend billing configuration (with hooks)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const StripeBackConfigSchema: v.RecordSchema<v.StringSchema<undefined>, v.ObjectSchema<{
    readonly type: v.PicklistSchema<["StripePayment", "StripeSubscription"], undefined>;
    readonly name: v.StringSchema<undefined>;
    readonly price: v.NumberSchema<undefined>;
    readonly currency: v.StringSchema<undefined>;
    /** Stripe price ID (fixed pricing). Optional for dynamic pricing products. */
    readonly priceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Default amount in cents (dynamic pricing). */
    readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    /** Product name for Stripe checkout (dynamic pricing). */
    readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
    /** Maximum allowed unit amount in cents. Security cap. */
    readonly maxUnitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
    readonly tier: v.StringSchema<undefined>;
    readonly duration: v.StringSchema<undefined>;
    readonly description: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
    readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
}, undefined>, undefined>;
/**
 * Helper to validate frontend config at runtime
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateStripeFrontConfig(config: unknown): {
    [x: string]: {
        name: string;
        price: string;
        currency: string;
        description?: string | undefined;
        features?: string[] | undefined;
        priceId?: string | undefined;
        unitAmount?: number | undefined;
        productName?: string | undefined;
        allowPromotionCodes?: boolean | undefined;
    };
};
/**
 * Helper to validate backend config at runtime
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateStripeBackConfig(config: unknown): {
    [x: string]: {
        type: "StripePayment" | "StripeSubscription";
        name: string;
        price: number;
        currency: string;
        priceId?: string | undefined;
        unitAmount?: number | undefined;
        productName?: string | undefined;
        maxUnitAmount?: number | undefined;
        tier: string;
        duration: string;
        description?: string | undefined;
        metadata?: {
            [x: string]: string;
        } | undefined;
        allowPromotionCodes?: boolean | undefined;
    };
};
/**
 * Validate all billing schemas
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateBillingSchemas(): {
    success: boolean;
    results: {
        createCheckoutSessionRequest: v.SafeParseResult<v.SchemaWithPipe<readonly [v.ObjectSchema<{
            readonly userId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
            readonly productId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
            /** Stripe price ID (fixed pricing mode) */
            readonly priceId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
            /** Amount in cents (dynamic pricing mode) */
            readonly unitAmount: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>, undefined>;
            /** Product name shown on Stripe checkout (dynamic pricing mode) */
            readonly productName: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>, undefined>;
            /** Currency code, defaults to 'eur' (dynamic pricing mode) */
            readonly currency: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.LengthAction<string, 3, "Currency must be 3-letter ISO code">]>, undefined>;
            readonly successUrl: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
            readonly cancelUrl: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>;
            readonly customerEmail: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
            readonly userEmail: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>, undefined>;
            readonly metadata: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.StringSchema<undefined>, undefined>, undefined>;
            readonly allowPromotionCodes: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
            readonly mode: v.OptionalSchema<v.PicklistSchema<["payment", "subscription"], undefined>, undefined>;
        }, undefined>, v.CheckAction<{
            userId?: string | undefined;
            productId?: string | undefined;
            priceId?: string | undefined;
            unitAmount?: number | undefined;
            productName?: string | undefined;
            currency?: string | undefined;
            successUrl: string;
            cancelUrl: string;
            customerEmail?: string | undefined;
            userEmail?: string | undefined;
            metadata?: {
                [x: string]: string;
            } | undefined;
            allowPromotionCodes?: boolean | undefined;
            mode?: "payment" | "subscription" | undefined;
        }, "Either priceId or (unitAmount + productName) is required">]>>;
        createCheckoutSessionResponse: v.SafeParseResult<v.ObjectSchema<{
            readonly sessionId: v.StringSchema<undefined>;
            readonly sessionUrl: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>;
        }, undefined>>;
        subscriptionData: v.SafeParseResult<v.ObjectSchema<{
            readonly userId: v.StringSchema<undefined>;
            readonly tier: v.StringSchema<undefined>;
            readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
            readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
            readonly customerId: v.StringSchema<undefined>;
            readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
            readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
            readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
        }, undefined>>;
        subscriptionClaims: v.SafeParseResult<v.ObjectSchema<{
            readonly tier: v.StringSchema<undefined>;
            readonly subscriptionId: v.NullableSchema<v.StringSchema<undefined>, undefined>;
            readonly customerId: v.StringSchema<undefined>;
            readonly status: v.PicklistSchema<[string, ...string[]], undefined>;
            readonly subscriptionEnd: v.NullableSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>, undefined>;
            readonly cancelAtPeriodEnd: v.BooleanSchema<undefined>;
            readonly updatedAt: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
            readonly isDefault: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
        }, undefined>>;
        webhookEvent: v.SafeParseResult<v.ObjectSchema<{
            readonly id: v.StringSchema<undefined>;
            readonly type: v.StringSchema<undefined>;
            readonly data: v.ObjectSchema<{
                readonly object: v.AnySchema;
            }, undefined>;
            readonly created: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, undefined>]>;
        }, undefined>>;
        checkoutSessionMetadata: v.SafeParseResult<v.LooseObjectSchema<{
            readonly userId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
            readonly firebaseUid: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
            readonly productType: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        }, undefined>>;
    };
};

/**
 * @fileoverview Billing Types
 * @description Type definitions for billing domain. Defines billing provider types, checkout modes, billing adapter interfaces, subscription types, and billing-related interfaces.
 * Uses unified FeatureStatus enum for feature state management.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/** Billing provider types - Stripe only
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type BillingProvider = 'stripe';
/** Unified checkout mode type used everywhere
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CheckoutMode = 'payment' | 'subscription';
/** Billing adapter interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BillingAdapter {
    createCheckoutSession(request: CreateCheckoutSessionRequest): Promise<CreateCheckoutSessionResponse>;
    getProvider(): Promise<BillingProvider>;
    isAvailable(): Promise<boolean>;
}
/** Billing event types
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type BillingEvent = {
    type: 'subscription_updated';
    data: unknown;
} | {
    type: 'payment_succeeded';
    data: unknown;
} | {
    type: 'payment_failed';
    data: unknown;
};
/** Payment method types
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PaymentMethodType = 'card' | 'bank_account' | 'paypal' | 'apple_pay' | 'google_pay';
/** Payment method interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PaymentMethod {
    id: string;
    userId: string;
    type: PaymentMethodType;
    isDefault: boolean;
    last4?: string;
    brand?: string;
    expiryMonth?: number;
    expiryYear?: number;
    createdAt: string;
    updatedAt: string;
}
/** Billing provider configuration interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BillingProviderConfig {
    provider: BillingProvider;
    apiKey?: string;
    webhookSecret?: string;
    publishableKey?: string;
    testMode?: boolean;
}
/** Invoice interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface Invoice {
    id: string;
    userId: string;
    amount: number;
    currency: string;
    status: 'draft' | 'open' | 'paid' | 'void' | 'uncollectible';
    createdAt: string;
    dueDate?: string;
    paidAt?: string;
    description?: string;
    items: InvoiceItem[];
}
/**
 * Invoice item interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface InvoiceItem {
    id: string;
    description: string;
    amount: number;
    quantity: number;
    unitPrice: number;
}
/**
 * Subscription interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface Subscription {
    id: string;
    userId: string;
    status: 'active' | 'canceled' | 'incomplete' | 'incomplete_expired' | 'past_due' | 'trialing' | 'unpaid';
    currentPeriodStart: string;
    currentPeriodEnd: string;
    cancelAtPeriodEnd: boolean;
    canceledAt?: string;
    trialStart?: string;
    trialEnd?: string;
    createdAt: string;
    updatedAt: string;
}
/**
 * Stripe webhook event data
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeWebhookEvent {
    id: string;
    type: string;
    data: {
        /** Raw Stripe object payload — shape depends on event type */
        object: Record<string, unknown>;
    };
    created: number;
    livemode: boolean;
    pending_webhooks: number;
    request?: {
        id: string;
        idempotency_key?: string;
    };
}
/**
 * Schema for creating checkout session
 */
/**
 * Schema for processing payment success
 */
/**
 * Checkout session creation request
 */
/**
 * Checkout session response
 */
/**
 * Refresh subscription request
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RefreshSubscriptionRequest {
    userId: string;
}
/**
 * Stripe provider interface for billing operations
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeProvider {
    createCheckoutSession(params: {
        priceId?: string;
        /** Amount in cents (dynamic pricing mode, used with price_data) */
        unitAmount?: number;
        /** Product name for Stripe checkout (dynamic pricing mode) */
        productName?: string;
        /** Currency code, defaults to 'eur' */
        currency?: string;
        userId: string;
        successUrl: string;
        cancelUrl: string;
        metadata?: Record<string, string>;
        customerEmail?: string;
        allowPromotionCodes?: boolean;
    }): Promise<CreateCheckoutSessionResponse>;
    getSubscription(userId: string): Promise<Subscription | null>;
    cancelSubscription(subscriptionId: string): Promise<boolean>;
    updateSubscription(subscriptionId: string, updates: Partial<Subscription>): Promise<Subscription>;
}
/**
 * Refresh subscription response
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RefreshSubscriptionResponse {
    success: boolean;
    subscription: Subscription;
}
/**
 * Process payment success request
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ProcessPaymentSuccessRequest {
    sessionId: string;
}
/**
 * Process payment success response
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ProcessPaymentSuccessResponse {
    success: boolean;
    sessionId: string;
}
/**
 * Billing-specific error codes for functions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type BillingErrorCode = 'unknown' | 'unauthenticated' | 'invalid_request' | 'stripe_error' | 'subscription_not_found' | 'checkout_session_not_found' | 'webhook_verification_failed' | 'rate_limit_exceeded' | 'insufficient_permissions' | 'invalid_webhook_signature' | 'checkout_blocked';
/**
 * Stripe checkout session creation request
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeCheckoutRequest {
    /** Stripe price ID (fixed pricing mode) */
    priceId?: string;
    /** Amount in cents (dynamic pricing mode, used with price_data) */
    unitAmount?: number;
    /** Product name for Stripe checkout (dynamic pricing mode) */
    productName?: string;
    /** Currency code, defaults to 'eur' (dynamic pricing mode) */
    currency?: string;
    /** User email for the subscription */
    userEmail: string;
    /** URL to redirect to on successful payment */
    successUrl: string;
    /** URL to redirect to on cancelled payment */
    cancelUrl: string;
    /** Optional metadata to attach to the session */
    metadata?: Record<string, string>;
    /** Customer email address */
    customerEmail?: string;
    /** Whether to allow promotion codes */
    allowPromotionCodes?: boolean;
    /** Trial period in days */
    trialPeriodDays?: number;
    /** Collection method for the subscription */
    collectionMethod?: 'charge_automatically' | 'send_invoice';
    /** Payment method types to allow */
    paymentMethodTypes?: string[];
    /** Billing address collection requirement */
    billingAddressCollection?: 'auto' | 'required';
    /** Tax ID collection requirement */
    taxIdCollection?: {
        enabled: boolean;
    };
    /** Checkout mode - payment or subscription */
    mode?: CheckoutMode;
}
/**
 * Stripe checkout session response
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeCheckoutResponse {
    /** Stripe session ID */
    sessionId: string;
    /** URL to redirect the user to complete payment */
    sessionUrl: string | null;
    /** Whether the session was created successfully */
    success: boolean;
    /** Error message if creation failed */
    error?: string;
}
/**
 * Stripe subscription data structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeSubscriptionData {
    /** Stripe subscription ID */
    id: string;
    /** Customer ID */
    customer: string;
    /** Subscription status */
    status: 'incomplete' | 'incomplete_expired' | 'trialing' | 'active' | 'past_due' | 'canceled' | 'unpaid';
    /** Current period start timestamp */
    current_period_start: number;
    /** Current period end timestamp */
    current_period_end: number;
    /** Whether the subscription will cancel at period end */
    cancel_at_period_end: boolean;
    /** When the subscription was canceled */
    canceled_at?: number;
    /** Trial start timestamp */
    trial_start?: number;
    /** Trial end timestamp */
    trial_end?: number;
    /** When the subscription was created */
    created: number;
    /** When the subscription was last updated */
    updated: number;
    /** Subscription items */
    items: {
        data: Array<{
            id: string;
            price: {
                id: string;
                unit_amount: number;
                currency: string;
                recurring: {
                    interval: 'day' | 'week' | 'month' | 'year';
                    interval_count: number;
                };
                product: string;
            };
            quantity: number;
        }>;
    };
    /** Default payment method */
    default_payment_method?: string;
    /** Collection method */
    collection_method: 'charge_automatically' | 'send_invoice';
    /** Days until due for invoices */
    days_until_due?: number;
    /** Subscription metadata */
    metadata: Record<string, string>;
}
/**
 * Stripe payment method data structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripePaymentMethod {
    /** Stripe payment method ID */
    id: string;
    /** Customer ID */
    customer: string;
    /** Payment method type */
    type: 'card' | 'bank_account' | 'us_bank_account' | 'sepa_debit' | 'ideal' | 'sofort' | 'bancontact' | 'p24' | 'giropay' | 'eps' | 'alipay' | 'wechat_pay';
    /** Card details (if type is 'card') */
    card?: {
        brand: 'amex' | 'diners' | 'discover' | 'jcb' | 'mastercard' | 'unionpay' | 'visa' | 'unknown';
        country: string;
        exp_month: number;
        exp_year: number;
        fingerprint: string;
        funding: 'credit' | 'debit' | 'prepaid' | 'unknown';
        last4: string;
        three_d_secure_usage?: {
            supported: boolean;
        };
        wallet?: {
            type: 'amex_express_checkout' | 'apple_pay' | 'google_pay' | 'masterpass' | 'samsung_pay' | 'visa_checkout';
            dynamic_last4?: string;
        };
    };
    /** Bank account details (if type is 'bank_account') */
    bank_account?: {
        account_holder_type: 'individual' | 'company';
        bank_name: string;
        country: string;
        currency: string;
        fingerprint: string;
        last4: string;
        routing_number: string;
        status: 'new' | 'validated' | 'verified' | 'verification_failed' | 'errored';
    };
    /** Billing details */
    billing_details: {
        address?: {
            city?: string;
            country?: string;
            line1?: string;
            line2?: string;
            postal_code?: string;
            state?: string;
        };
        email?: string;
        name?: string;
        phone?: string;
    };
    /** When the payment method was created */
    created: number;
    /** Whether this is the default payment method */
    is_default?: boolean;
    /** Payment method metadata */
    metadata: Record<string, string>;
}
/**
 * Stripe invoice data structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeInvoice {
    /** Stripe invoice ID */
    id: string;
    /** Customer ID */
    customer: string;
    /** Invoice amount */
    amount_due: number;
    /** Invoice amount paid */
    amount_paid: number;
    /** Invoice amount remaining */
    amount_remaining: number;
    /** Currency code */
    currency: string;
    /** Invoice status */
    status: 'draft' | 'open' | 'paid' | 'void' | 'uncollectible';
    /** When the invoice was created */
    created: number;
    /** When the invoice is due */
    due_date?: number;
    /** When the invoice was paid */
    paid_at?: number;
    /** When the invoice was voided */
    voided_at?: number;
    /** Invoice description */
    description?: string;
    /** Invoice line items */
    lines: {
        data: Array<{
            id: string;
            amount: number;
            currency: string;
            description?: string;
            quantity: number;
            unit_amount: number;
            price?: {
                id: string;
                unit_amount: number;
                currency: string;
                recurring?: {
                    interval: 'day' | 'week' | 'month' | 'year';
                    interval_count: number;
                };
                product: string;
            };
        }>;
    };
    /** Invoice metadata */
    metadata: Record<string, string>;
    /** Subscription ID (if applicable) */
    subscription?: string;
    /** Total amount */
    total: number;
    /** Tax amount */
    tax?: number;
    /** Tax rate applied */
    tax_rate?: number;
}
/**
 * Stripe customer data structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeCustomer {
    /** Stripe customer ID */
    id: string;
    /** Customer email */
    email?: string;
    /** Customer name */
    name?: string;
    /** Customer description */
    description?: string;
    /** Customer phone */
    phone?: string;
    /** Customer address */
    address?: {
        city?: string;
        country?: string;
        line1?: string;
        line2?: string;
        postal_code?: string;
        state?: string;
    };
    /** Customer balance */
    balance: number;
    /** Currency code */
    currency?: string;
    /** When the customer was created */
    created: number;
    /** When the customer was last updated */
    updated: number;
    /** Customer metadata */
    metadata: Record<string, string>;
    /** Default payment method */
    default_source?: string;
    /** Whether the customer is deleted */
    deleted?: boolean;
    /** Customer tax IDs */
    tax_ids?: {
        data: Array<{
            id: string;
            type: 'eu_vat' | 'br_cnpj' | 'br_cpf' | 'gb_vat' | 'nz_gst' | 'au_abn' | 'au_arn' | 'in_gst' | 'no_vat' | 'za_vat' | 'ch_vat' | 'mx_rfc' | 'sg_uen' | 'ru_inn' | 'ru_kpp' | 'ca_bn' | 'hk_br' | 'es_cif' | 'tw_vat' | 'th_vat' | 'jp_cn' | 'jp_rn' | 'li_uid' | 'my_itn' | 'us_ein' | 'kr_brn' | 'ca_gst_hst' | 'ca_qst' | 'ca_pst_bc' | 'ca_pst_mb' | 'ca_pst_sk' | 'my_sst' | 'sg_gst' | 'ae_trn' | 'cl_tin' | 'sa_vat' | 'id_npwp';
            value: string;
        }>;
    };
}
/**
 * Stripe product data structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeProduct {
    /** Stripe product ID */
    id: string;
    /** Product name */
    name: string;
    /** Product description */
    description?: string;
    /** Product images */
    images: string[];
    /** Product metadata */
    metadata: Record<string, string>;
    /** Whether the product is active */
    active: boolean;
    /** When the product was created */
    created: number;
    /** When the product was last updated */
    updated: number;
    /** Product type */
    type: 'service' | 'good';
    /** Product URL */
    url?: string;
    /** Product statement descriptor */
    statement_descriptor?: string;
    /** Product unit label */
    unit_label?: string;
    /** Product tax code */
    tax_code?: string;
}
/**
 * Stripe price data structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripePrice {
    /** Stripe price ID */
    id: string;
    /** Product ID */
    product: string;
    /** Price amount in cents */
    unit_amount: number;
    /** Currency code */
    currency: string;
    /** Price type */
    type: 'one_time' | 'recurring';
    /** Recurring interval (if type is 'recurring') */
    recurring?: {
        interval: 'day' | 'week' | 'month' | 'year';
        interval_count: number;
        trial_period_days?: number;
        usage_type: 'licensed' | 'metered';
    };
    /** Whether the price is active */
    active: boolean;
    /** When the price was created */
    created: number;
    /** When the price was last updated */
    updated: number;
    /** Price metadata */
    metadata: Record<string, string>;
    /** Price nickname */
    nickname?: string;
    /** Price tiers (for graduated pricing) */
    tiers?: Array<{
        up_to: number | 'inf';
        unit_amount: number;
        flat_amount?: number;
    }>;
    /** Price tiers mode */
    tiers_mode?: 'graduated' | 'volume';
    /** Price transform quantity */
    transform_quantity?: {
        divide_by: number;
        round: 'up' | 'down';
    };
    /** Price lookup key */
    lookup_key?: string;
}
/**
 * Result of a beforeCheckout hook invocation.
 * Allows blocking checkout or overriding pricing before Stripe session creation.
 */
interface BeforeCheckoutResult {
    /** Whether checkout is allowed to proceed */
    allowed: boolean;
    /** Reason for blocking (shown in error response) */
    reason?: string;
    /** Optional overrides applied to checkout options before Stripe session creation */
    overrides?: Partial<Pick<CheckoutOptions, 'unitAmount' | 'productName'>>;
}
/**
 * Hook called before Stripe checkout session creation.
 * Use for ownership checks, status validation, server-resolved pricing.
 *
 * @param userId - Authenticated user ID
 * @param options - Checkout options from the client request
 * @param metadata - Request metadata (sanitized)
 * @returns Whether to allow checkout, optional reason, optional overrides
 */
type BeforeCheckoutHook = (userId: string, options: CheckoutOptions, metadata: Record<string, string>) => Promise<BeforeCheckoutResult>;
/**
 * Checkout options for Stripe checkout session
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CheckoutOptions {
    /** Stripe price ID (fixed pricing mode) */
    priceId?: string;
    /** Amount in cents (dynamic pricing mode) */
    unitAmount?: number;
    /** Product name for Stripe checkout (dynamic pricing mode) */
    productName?: string;
    /** Currency code, defaults to 'eur' (dynamic pricing mode) */
    currency?: string;
    mode: 'payment' | 'subscription';
    successUrl?: string;
    cancelUrl?: string;
    metadata?: Record<string, string>;
    allowPromotionCodes?: boolean;
}
/**
 * Billing API type - complete interface for useStripeBilling hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BillingAPI {
    /**
     * Unified feature status - single source of truth for billing state.
     * Replaces deprecated `loading` boolean flag.
     * - `initializing`: Billing is loading/initializing
     * - `ready`: Billing fully operational
     * - `degraded`: Billing unavailable (feature not installed/consent not given)
     * - `error`: Billing encountered error
     */
    status: FeatureStatus;
    error: string | null;
    /**
     * Whether a billing operation is in progress.
     * For redirect operations (checkout, portal), the hook automatically shows
     * a fullscreen overlay with operation-specific messaging.
     */
    loading: boolean;
    checkout: (options: CheckoutOptions) => Promise<StripeCheckoutResponse>;
    cancelSubscription: () => Promise<{
        success: boolean;
        endsAt: string;
    }>;
    changePlan: (newPriceId: string, billingConfigKey: string) => Promise<{
        success: boolean;
    }>;
    refreshStatus: () => Promise<void>;
    openCustomerPortal: (returnUrl?: string) => Promise<void>;
    clearError: () => void;
    isAvailable: boolean;
}
/**
 * Frontend billing configuration type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type StripeFrontConfig = v.InferOutput<typeof StripeFrontConfigSchema>;
/**
 * Backend billing configuration type with hooks
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type StripeBackConfig = {
    [key: string]: {
        type: 'StripePayment' | 'StripeSubscription';
        name: string;
        price: number;
        currency: string;
        /** Stripe price ID (fixed pricing). Optional for dynamic pricing products. */
        priceId?: string;
        /** Default amount in cents (dynamic pricing). */
        unitAmount?: number;
        /** Product name for Stripe checkout (dynamic pricing). */
        productName?: string;
        /** Maximum allowed unit amount in cents. Security cap for client-provided amounts. */
        maxUnitAmount?: number;
        tier: string;
        duration: string;
        description?: string;
        metadata?: Record<string, string>;
        allowPromotionCodes?: boolean;
        onPurchaseSuccess?: (userId: string, metadata: Record<string, string>) => Promise<void>;
        onPurchaseFailure?: (userId: string, metadata: Record<string, string>) => Promise<void>;
        onSubscriptionCreated?: (userId: string, metadata: Record<string, string>) => Promise<void>;
        onSubscriptionRenewed?: (userId: string, metadata: Record<string, string>) => Promise<void>;
        onSubscriptionCancelled?: (userId: string, metadata: Record<string, string>) => Promise<void>;
        onPaymentFailed?: (userId: string, metadata: Record<string, string>) => Promise<void>;
        /** Hook called before Stripe checkout session creation. Can block or override pricing. */
        beforeCheckout?: BeforeCheckoutHook;
    };
};
/**
 * Stripe configuration interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeConfig {
    /** Stripe secret key for server-side operations */
    secretKey: string;
    /** Stripe publishable key for client-side operations */
    publishableKey: string;
    /** Stripe webhook secret for webhook verification */
    webhookSecret: string;
    /** Whether to use test mode */
    testMode: boolean;
    /** API version to use */
    apiVersion?: string;
    /** Maximum number of retries for failed requests */
    maxNetworkRetries?: number;
    /** Request timeout in milliseconds */
    timeout?: number;
    /** Additional configuration options */
    options?: {
        /** Whether to enable telemetry */
        telemetry?: boolean;
        /** App information */
        appInfo?: {
            name: string;
            version: string;
            url?: string;
        };
    };
}

/**
 * @fileoverview Authentication Types
 * @description Type definitions for authentication domain. Defines authentication partner types, user types, session types, and authentication-related interfaces.
 * Uses unified FeatureStatus enum for feature state management.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Authentication method type
 * 'popup' - Opens OAuth popup window (better for dev/localhost)
 * 'redirect' - Redirects to OAuth provider (better for production)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthMethod = 'redirect' | 'popup';
/**
 * Email verification status type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type EmailVerificationStatus = 'verified' | 'pending' | 'error';
/**
 * Email verification status constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const EMAIL_VERIFICATION_STATUS: {
    readonly VERIFIED: "verified";
    readonly PENDING: "pending";
    readonly ERROR: "error";
};
/**
 * Auth partner result interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthPartnerResult extends PartnerResult {
    partnerId: AuthPartnerId;
    metadata?: Record<string, any>;
}
/**
 * Partner state constants - Single source of truth for partner states
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const AUTH_PARTNER_STATE: {
    readonly IDLE: "idle";
    readonly LOADING: "loading";
    readonly ERROR: "error";
    readonly AUTHENTICATED: "authenticated";
};
/**
 * Auth partner state type - simple string constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthPartnerState = (typeof AUTH_PARTNER_STATE)[keyof typeof AUTH_PARTNER_STATE];
/**
 * Error type that supports Firebase errors and custom errors with code property
 * Note: DoNotDevError is avoided for account linking to preserve Firebase error codes
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthError = (Error & {
    code?: string;
}) | null;
/**
 * Contains authorization and user preference information
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UserProfile {
    /** The user's unique identifier (matches AuthUser.id) */
    userId: string;
    /** The user's display name */
    displayName?: string;
    /** The user's email address */
    email?: string;
    /** The user's profile photo URL */
    photoURL?: string;
    /** Additional profile data */
    [key: string]: unknown;
}
/**
 * Factory function to create default user profile
 * @param userId - User ID for the profile
 * @returns Default user profile with minimal required fields
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function createDefaultUserProfile(userId: string): UserProfile;
/**
 * Provides a unified interface for accessing all user data
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UserContext {
    /** Core authentication data */
    auth: AuthUser;
    /** User profile information */
    profile: UserProfile;
    /** Subscription information */
    subscription: UserSubscription;
}
/**
 * Extends SubscriptionClaims with calculated or derived subscription status information.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SubscriptionInfo extends SubscriptionClaims {
    /** Indicates if the subscription is currently active (typically based on subscriptionEnd) */
    isActive: boolean;
    /** Number of days remaining in the subscription, or null if not applicable */
    daysRemaining: number | null;
    /** Array of feature IDs available to the user based on their subscription */
    features: string[];
}
/**
 * Result type for the useAuthPartner hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthPartnerHookResult {
    /** Current authentication state from the partner */
    partnerState: AuthPartnerState;
    /** Whether a connection operation is in progress */
    isConnecting: boolean;
    /** Whether the partner is currently connected */
    isConnected: boolean;
    /** Current error message, or null if no error */
    error: Error | null;
    /** Function to connect to this partner */
    connect: (options?: {
        redirectUri?: string;
        onSuccess?: (result: AuthPartnerResult) => void;
        onError?: (error: Error) => void;
    }) => Promise<void>;
    /** Function to disconnect from this partner */
    disconnect: () => Promise<boolean>;
}
/**
 * Result type for the useAuthCore hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthCoreHookResult {
    user: AuthUser | null;
    authenticated: boolean;
    loading: boolean;
    error: string | null;
    signIn: (email: string, password: string) => Promise<void>;
    signUp: (email: string, password: string) => Promise<void>;
    signOut: () => Promise<void>;
    resetPassword: (email: string) => Promise<void>;
    updateProfile: (updates: Partial<AuthUser>) => Promise<void>;
}
/**
 * Result type for the useAuthToken hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthTokenHookResult {
    token: string | null;
    status: TokenStatus;
    expiresAt: Date | null;
    refreshToken: () => Promise<string | null>;
    getAccessToken: () => Promise<string | null>;
}
/**
 * Result type for the useSubscription hook
 * NOTE: subscription is now always present
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SubscriptionHookResult {
    subscription: SubscriptionInfo;
    refreshSubscription: () => Promise<void>;
    hasFeature: (featureId: string) => boolean;
    hasTier: (requiredTier: string) => boolean;
}
/**
 * Result type for the useAdminCheck hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AdminCheckHookResult {
    isAdmin: boolean;
    isLoading: boolean;
}
/**
 * Result type for the useNetworkStatus hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface NetworkStatusHookResult {
    online: boolean;
    connectionType: string;
}
/**
 * Options for redirect behavior
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthRedirectOptions {
    /** If true, only allow admin users */
    adminOnly?: boolean;
    /** If true, require email verification */
    requireEmailVerification?: boolean;
    /** If true, require subscription */
    requireSubscription?: boolean;
    /** Redirect URL if conditions not met */
    redirectTo?: string;
}
/**
 * Result type for the useAuthRedirect hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthRedirectHookResult {
    authenticated: boolean;
    isAdmin: boolean;
    isEmailVerified: boolean;
    hasSubscription: boolean;
    shouldRedirect: boolean;
    redirectTo?: string;
}
/**
 * Result type for the useEmailVerification hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface EmailVerificationHookResult {
    isVerified: boolean;
    isLoading: boolean;
    error: string | null;
    sendVerificationEmail: () => Promise<void>;
    checkVerificationStatus: () => Promise<void>;
}
/**
 * Result type for the useFeatureAccess hook
 * NOTE: subscription is now always present
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FeatureAccessHookResult {
    hasFeature: (featureId: string) => boolean;
    hasTier: (requiredTier: string) => boolean;
    subscription: SubscriptionInfo;
}
/**
 * Result type for the useFeature hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FeatureHookResult {
    enabled: boolean;
}
/**
 * Result type for the useTierAccess hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface TierAccessHookResult {
    enabled: boolean;
}
/**
 * Represents a feature that can be enabled or disabled for users,
 * often tied to a specific subscription tier.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface Feature {
    /** Unique identifier for the feature */
    id: string;
    /** Human-readable name for the feature */
    name: string;
    /** Description of what the feature does */
    description?: string;
    /** Whether the feature is currently enabled */
    enabled: boolean;
    /** Required subscription tier for this feature */
    requiredTier?: string;
}
/**
 * Stores information specific to a user's identity from a particular authentication provider.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UserProviderData {
    /** The unique identifier for the authentication provider (e.g., 'google.com') */
    providerId: string;
    /** The user's unique identifier within this provider */
    uid: string;
    /** The user's email address from this provider */
    email?: string | null;
    /** The user's display name from this provider */
    displayName?: string | null;
    /** The user's photo URL from this provider */
    photoURL?: string | null;
    /** The user's phone number from this provider */
    phoneNumber?: string | null;
    /** Additional provider-specific data */
    [key: string]: any;
}
/**
 * Defines custom claims specifically for administrative users.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AdminClaims {
    /** Flag indicating if the user has administrative privileges */
    isAdmin: boolean;
    /** Optional role or permission level */
    role?: string;
    /** Optional department or team */
    department?: string;
    /** Additional admin-specific claims */
    [key: string]: any;
}
/**
 * Information stored in sessionStorage for account linking flow
 * Firebase 12.3 stores credentials, we only store UI state
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AccountLinkingInfo {
    email: string;
    existingProvider: AuthPartnerId;
    newProvider: string;
    timestamp: number;
}
/**
 * Represents the outcome of an attempt to link an additional authentication provider.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AccountLinkResult {
    /** Indicates whether the overall linking process was successful */
    success: boolean;
    /** The provider that was linked */
    provider: string;
    /** Error message if the linking failed */
    error?: string;
    /** Additional data about the linked account */
    data?: Record<string, any>;
}
/**
 * Authentication state interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthState {
    user: AuthUser | null;
    authenticated: boolean;
    userId: string | null;
    loading: boolean;
    error: AuthError;
    userProfile: UserProfile | null;
    userSubscription: UserSubscription | null;
    partnerStates: Record<AuthPartnerId, AuthPartnerState>;
    partnerError: {
        partnerId: AuthPartnerId;
        error: AuthError;
    } | null;
    emailVerification: {
        status: EmailVerificationStatus;
        error?: string;
    };
    /**
     * Password reset recovery mode.
     * Set by provider when PASSWORD_RECOVERY event fires (Supabase)
     * or when oobCode is detected in URL (Firebase).
     * Components use this to show the "set new password" UI.
     */
    passwordResetPending: boolean;
    authService: unknown;
    /**
     * Unified feature status - single source of truth for auth state.
     * Replaces deprecated boolean flags (initialized, authStateChecked).
     *
     * **Lifecycle timeline:**
     * 1. Store created → `status: 'initializing'` (show loader)
     * 2. Auth service init + first callback → `status: 'ready'` (normal operation)
     * 3. If feature disabled/unavailable → `status: 'degraded'` (protected routes redirect with error)
     * 4. If init fails → `status: 'error'` (protected routes redirect with error)
     *
     * **Guard behavior:**
     * - `degraded` + protected route → redirect to auth route with `?error=auth_unavailable`
     * - `error` + protected route → redirect to auth route with `?error=auth_error`
     * - `initializing` → show loader, don't redirect
     * - `ready` → perform normal auth checks
     *
     * @see FEATURE_STATUS for possible values
     */
    status: FeatureStatus;
}
/**
 * Authentication actions interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthActions {
    setPartnerState: (partnerId: AuthPartnerId, state: AuthPartnerState, error?: AuthError) => void;
    getPartnerState: (partnerId: AuthPartnerId) => AuthPartnerState;
    clearAllPartnerStates: () => void;
    setAuthenticated: (user: AuthUser, subscription: UserSubscription, profile: UserProfile) => void;
    setUnauthenticated: () => void;
    setAuthLoading: (loading: boolean) => void;
    setAuthError: (error: AuthError) => void;
    clearAuthError: () => void;
    /** Set unified status - single source of truth */
    setStatus: (status: FeatureStatus) => void;
    getCustomClaim: (claim: string) => unknown;
    getCustomClaims: () => Record<string, unknown>;
    emailVerification: {
        status: EmailVerificationStatus;
        error?: string;
    };
    setPasswordResetPending: (pending: boolean) => void;
    setLoading: (loading: boolean) => void;
    setError: (error: AuthError) => void;
    clearError: () => void;
    reset: () => void;
    setAuthService: (authService: unknown) => void;
    getCustomClaimLocal: (claim: string) => unknown;
    getCustomClaimsLocal: () => Record<string, unknown>;
    setEmailVerificationStatus: (status: EmailVerificationStatus, error?: string) => void;
    setUserProfile: (profile: UserProfile) => void;
    setUserSubscription: (subscription: UserSubscription) => void;
}
/**
 * Authentication context value interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthContextValue {
    /** The currently authenticated user object, or null if unauthenticated */
    user: AuthUser | null;
    /** Whether the user is currently authenticated */
    authenticated: boolean;
    /** Whether an authentication operation is in progress */
    loading: boolean;
    /** Current error message, or null if no error */
    error: string | null;
    /** The user's role */
    role: UserRole;
    /** The user's subscription information, or null if unauthenticated or not yet loaded */
    subscription: SubscriptionInfo | null;
    /** Current authentication token */
    token: string | null;
    /** Token status */
    tokenStatus: TokenStatus;
    /** When the token expires */
    tokenExpiresAt: Date | null;
    /** Sign in with email and password */
    signIn: (email: string, password: string) => Promise<void>;
    /** Sign up with email and password */
    signUp: (email: string, password: string) => Promise<void>;
    /** Sign out the current user */
    signOut: () => Promise<void>;
    /** Reset password for email */
    resetPassword: (email: string) => Promise<void>;
    /** Update user profile */
    updateProfile: (updates: Partial<AuthUser>) => Promise<void>;
    /** Refresh the authentication token */
    refreshToken: () => Promise<string | null>;
    /** Get the current access token */
    getAccessToken: () => Promise<string | null>;
    /** Check if user has a specific role */
    hasRole: (role: UserRole) => boolean;
    /** Check if user has access to a feature */
    hasFeature: (featureId: string) => boolean;
    /** Check if user has access to a tier */
    hasTier: (requiredTier: string) => boolean;
}
/**
 * Props for the AuthProvider component
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthProviderProps {
    /** Child components that will have access to the authentication context */
    children: ReactNode;
}
/**
 * Result of an authentication operation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthResult {
    /** The authenticated user */
    user: AuthUser;
    /** Whether the operation was successful */
    success: boolean;
    /** Whether this is a new user (for sign-up operations) */
    isNewUser?: boolean;
    /** Error message if the operation failed */
    error?: string;
}
/**
 * Get user auth status response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface GetUserAuthStatusResponse {
    userId: string;
    isAuthenticated: boolean;
    customClaims: Record<string, any>;
    hasClaims: boolean;
    claimCount: number;
}
/**
 * Get custom claims response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface GetCustomClaimsResponse {
    claims: Record<string, any>;
    userId: string;
}
/**
 * Set custom claims response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SetCustomClaimsResponse {
    success: boolean;
    userId: string;
    claims: Record<string, any>;
}
/**
 * Remove custom claims response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RemoveCustomClaimsResponse {
    success: boolean;
    userId: string;
    removedClaims: string[];
    remainingClaims: Record<string, any>;
}
/**
 * Function to unsubscribe from auth state changes
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type UnsubscribeFn = () => void;
/**
 * Optional metadata passed to signup methods.
 * Stored in provider-specific user metadata (Supabase `raw_user_meta_data`, Firebase user doc).
 */
interface SignUpMetadata {
    /** ISO-8601 timestamp of GDPR consent acceptance */
    gdpr_consent_at?: string;
    /** Version identifier of the ToS document accepted */
    gdpr_tos_version?: string;
    /** Extensible for consumer-specific fields */
    [key: string]: unknown;
}
/**
 * Authentication provider interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthProvider {
    /**
     * Initialize the auth provider
     */
    initialize(): Promise<void>;
    /**
     * Get the current user
     */
    getCurrentUser(): Promise<AuthUser | null>;
    /**
     * Sign in with email and password
     */
    signInWithEmailAndPassword(email: string, password: string): Promise<AuthUser>;
    /**
     * Sign up with email and password
     */
    createUserWithEmailAndPassword(email: string, password: string, metadata?: SignUpMetadata): Promise<AuthUser>;
    /**
     * Sign out the current user
     */
    signOut(): Promise<void>;
    /**
     * Reset password for email
     */
    sendPasswordResetEmail(email: string): Promise<void>;
    /**
     * Update user profile
     */
    updateUserProfile(updates: Partial<AuthUser>): Promise<void>;
    /**
     * Get the current access token
     */
    getAccessToken(): Promise<string | null>;
    /**
     * Refresh the authentication token
     */
    refreshToken(): Promise<string | null>;
    /**
     * Subscribe to auth state changes
     */
    onAuthStateChanged(callback: (user: AuthUser | null) => void): UnsubscribeFn;
    /**
     * Check if user has a specific role
     */
    hasRole(role: UserRole): Promise<boolean>;
    /**
     * Check if user has access to a feature
     */
    hasFeature(featureId: string): Promise<boolean>;
    /**
     * Check if user has access to a tier
     */
    hasTier(requiredTier: string): Promise<boolean>;
    signInWithEmail(email: string, password: string): Promise<AuthResult | null>;
    createUserWithEmail(email: string, password: string, metadata?: SignUpMetadata): Promise<AuthResult | null>;
    signInWithPartner(partnerId: AuthPartnerId, method?: AuthMethod): Promise<AuthResult | null>;
    linkWithPartner(partnerId: AuthPartnerId, method?: AuthMethod): Promise<AuthResult | null>;
    signInWithGoogleCredential(credential: string): Promise<AuthResult | null>;
    updatePassword(newPassword: string): Promise<void>;
    /**
     * Verify a password reset code from the email callback link.
     * Returns the email address associated with the code.
     * @returns email address, or null if code is invalid/expired
     */
    verifyPasswordResetCode?(code: string): Promise<string | null>;
    /**
     * Confirm a password reset with the code from the email and the new password.
     * After success, user can sign in with the new password.
     */
    confirmPasswordReset?(code: string, newPassword: string): Promise<void>;
    /**
     * Get the password reset redirect path for this provider.
     * Used to build the redirect URL in password reset emails.
     */
    getPasswordResetRedirectUrl?(): string;
    sendEmailVerification(): Promise<void>;
    sendSignInLinkToEmail(email: string, actionCodeSettings?: {
        url: string;
        handleCodeInApp: boolean;
    }): Promise<void>;
    signInWithEmailLink(email: string, emailLink?: string): Promise<AuthResult | null>;
    isSignInWithEmailLink(emailLink?: string): boolean;
    getEmailVerificationStatus(): Promise<{
        status: string;
    }>;
    isEmailVerificationEnabled(): Promise<boolean>;
    reauthenticateWithPassword(password: string): Promise<void>;
    reauthenticateWithProvider(partnerId: AuthPartnerId, method?: AuthMethod): Promise<void>;
    deleteAccount(password?: string): Promise<void>;
    /**
     * Set session persistence (remember me).
     * Provider-specific: Firebase uses browserLocal/browserSession persistence,
     * Supabase uses cookie duration, etc.
     * No-op if the provider doesn't support persistence control.
     *
     * @param remember - true for persistent session, false for session-only
     */
    setRememberMe?(remember: boolean): Promise<void>;
}
/**
 * Information about a token including its status and expiration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface TokenInfo {
    /** The actual token string or null if not available */
    token: string | null;
    /** Current status of the token */
    status: TokenStatus;
    /** When the token expires, or null if not available */
    expiresAt: Date | null;
    /** When the token was last refreshed */
    lastRefreshed?: Date;
    /** Number of seconds until expiration */
    expiresIn?: number;
}
/**
 * Auth API type - complete interface for useAuth hook
 *
 * This interface defines all properties available through useAuth('propertyName').
 * Properties are categorized by their behavior:
 * - **State** (reactive): Re-renders when value changes
 * - **Methods** (stable): Never re-renders, always same reference
 * - **Computed** (derived): Re-renders when dependencies change
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthAPI {
    user: AuthUser | null;
    userProfile: UserProfile | null;
    userSubscription: UserSubscription | null;
    loading: boolean;
    error: AuthError | null;
    emailVerification: {
        status: string;
        error?: string;
    };
    passwordResetPending: boolean;
    partnerError: {
        partnerId: AuthPartnerId;
        error: string;
    } | null;
    /**
     * Unified feature status - single source of truth for auth state.
     * Replaces deprecated boolean flags. See AuthState.status for detailed lifecycle.
     */
    status: FeatureStatus;
    getPartnerState: (partnerId: AuthPartnerId) => string;
    setPartnerState: (partnerId: AuthPartnerId, state: string, error?: string) => void;
    hasRole: (role: string) => Promise<boolean>;
    hasTier: (tier: string) => Promise<boolean>;
    hasFeature: (feature: string) => Promise<boolean>;
    getCustomClaims: () => Record<string, unknown>;
    getCustomClaim: (claim: string) => unknown;
    signInWithEmail: (email: string, password: string) => Promise<AuthResult | null>;
    createUserWithEmail: (email: string, password: string, metadata?: SignUpMetadata) => Promise<AuthResult | null>;
    signInWithPartner: (partnerId: AuthPartnerId, method?: string) => Promise<AuthResult | null>;
    linkWithPartner: (partnerId: AuthPartnerId, method?: string) => Promise<AuthResult | null>;
    signInWithGoogleCredential: (credential: string) => Promise<AuthResult | null>;
    signOut: () => Promise<void>;
    sendPasswordResetEmail: (email: string) => Promise<void>;
    updatePassword: (newPassword: string) => Promise<void>;
    verifyPasswordResetCode: (code: string) => Promise<string | null>;
    confirmPasswordReset: (code: string, newPassword: string) => Promise<void>;
    sendEmailVerification: () => Promise<void>;
    getEmailVerificationStatus: () => Promise<{
        status: string;
    }>;
    isEmailVerificationEnabled: () => Promise<boolean>;
    sendSignInLinkToEmail: (email: string, settings?: any) => Promise<void>;
    signInWithEmailLink: (email: string, link?: string) => Promise<AuthResult | null>;
    isSignInWithEmailLink: (link?: string) => boolean;
    getCurrentUser: () => Promise<AuthUser | null>;
    reauthenticateWithPassword: (password: string) => Promise<void>;
    reauthenticateWithProvider: (partnerId: AuthPartnerId, method?: AuthMethod) => Promise<void>;
    deleteAccount: (password?: string) => Promise<void>;
    setRememberMe: (remember: boolean) => Promise<void>;
    isAuthenticated: boolean;
    userRole: string;
    userTier: string;
    /**
     * Capability-based access control object.
     * Usage: `const can = useAuth('can'); if (can.edit('licenses')) { ... }`
     */
    can: CanAPI;
    isAvailable: boolean;
}
/**
 * Capability-based access control API
 *
 * Provides granular permission checks based on resources and custom capabilities.
 * Permissions are derived from userProfile.permissions array (format: "resource:action")
 * and user role (admin bypasses all checks).
 *
 * @example
 * ```typescript
 * const can = useAuth('can');
 * if (can.view('dashboard')) { ... }
 * if (can.edit('licenses')) { ... }
 * if (can.perform('approve-budget', { amount: 5000 })) { ... }
 * ```
 *
 * @version 0.1.0
 * @since 0.0.3
 * @author AMBROISE PARK Consulting
 */
interface CanAPI {
    /** Check if user can navigate to a route (replaces canAccess) */
    navigate: (config: PageAuth | false) => boolean;
    /** Check if user can view a resource */
    view: (resource: string) => boolean;
    /** Check if user can edit a resource */
    edit: (resource: string) => boolean;
    /** Check if user can delete a resource */
    delete: (resource: string) => boolean;
    /** Check if user can create a resource */
    create: (resource: string) => boolean;
    /** Check custom capability with optional context */
    perform: (action: string, context?: Record<string, any>) => boolean;
    /** Check if user has specific permission string */
    has: (permission: string) => boolean;
}

/**
 * @fileoverview CRUD Constants
 * @description Constants for CRUD domain. Defines visibility levels for entity fields and supported field types for entities.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Visibility levels for entity fields (runtime constants)
 * Controls who can SEE this field in responses
 * Matches USER_ROLES hierarchy + technical + hidden + owner
 *
 * - guest: Everyone (even unauthenticated)
 * - user: Authenticated users (users see guest + user fields)
 * - admin: Admins only (admins see guest + user + admin fields)
 * - super: Super admins only (see all non-technical fields)
 * - technical: System fields (shown as read-only in edit forms, admins+ only)
 * - hidden: Never exposed to client (passwords, tokens, API keys)
 * - owner: Visible only when request.auth.uid matches one of entity.ownership.ownerFields on the document
 */
declare const VISIBILITY: {
    readonly GUEST: "guest";
    readonly USER: "user";
    readonly ADMIN: "admin";
    readonly SUPER: "super";
    readonly TECHNICAL: "technical";
    readonly HIDDEN: "hidden";
    readonly OWNER: "owner";
};
/**
 * Editable levels for entity fields (runtime constants)
 * Controls who can MODIFY this field
 * - true: Anyone who can see the field
 * - false: Nobody (read-only)
 * - 'user': Authenticated users+ (role hierarchy)
 * - 'admin': Admins+ (role hierarchy)
 * - 'super': Super admins only
 * - 'create-only': Editable on create, read-only after
 * - 'generated': DB-generated (excluded from forms and write schemas)
 * - 'computed': UI-computed (excluded from forms, included in writes)
 */
declare const EDITABLE: {
    /** Anyone who can see the field (follows visibility) */
    readonly TRUE: true;
    /** Read-only display in forms */
    readonly FALSE: false;
    /** Authenticated users+ */
    readonly USER: "user";
    /** Admin+ */
    readonly ADMIN: "admin";
    /** Super only */
    readonly SUPER: "super";
    /** Editable on create, read-only after */
    readonly CREATE_ONLY: "create-only";
    /** DB-generated column (PostgreSQL GENERATED ALWAYS) — excluded from forms and write schemas */
    readonly GENERATED: "generated";
    /** UI-computed field (derived from other fields) — excluded from forms, included in writes */
    readonly COMPUTED: "computed";
};
/**
 * Default access levels for entity operations
 * Opinionated framework defaults:
 * - Read is public by default (Level 0)
 * - Write operations require Admin by default (Level 2)
 */
declare const DEFAULT_ENTITY_ACCESS: {
    readonly create: "admin";
    readonly read: "guest";
    readonly update: "admin";
    readonly delete: "admin";
};
/**
 * Supported field types for entities (runtime constants)
 * Useful for UI renderers and documentation.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Supported filter operators for query where clauses.
 * Use these in framework code for consistency. Consumers can use string literals
 * (e.g. operator: 'in') — CrudOperator accepts them; no need to import CRUD_OPERATORS.
 */
declare const CRUD_OPERATORS: {
    readonly EQ: "==";
    readonly NEQ: "!=";
    readonly LT: "<";
    readonly LTE: "<=";
    readonly GT: ">";
    readonly GTE: ">=";
    readonly IN: "in";
    readonly NOT_IN: "not-in";
    readonly ARRAY_CONTAINS: "array-contains";
    readonly ARRAY_CONTAINS_ANY: "array-contains-any";
};
/** Union of operator string literals. Consumer apps may use e.g. operator: 'in' without importing CRUD_OPERATORS. */
type CrudOperator = (typeof CRUD_OPERATORS)[keyof typeof CRUD_OPERATORS];
/** Order direction for query orderBy */
declare const ORDER_DIRECTION: {
    readonly ASC: "asc";
    readonly DESC: "desc";
};
/** Sort direction for query orderBy clauses. */
type OrderDirection = (typeof ORDER_DIRECTION)[keyof typeof ORDER_DIRECTION];
/** Schema type for list queries (list vs listCard) */
declare const LIST_SCHEMA_TYPE: {
    readonly LIST: "list";
    readonly LIST_CARD: "listCard";
};
/** Schema variant for list queries (table vs card grid). */
type ListSchemaType = (typeof LIST_SCHEMA_TYPE)[keyof typeof LIST_SCHEMA_TYPE];
declare const FIELD_TYPES: readonly ["address", "array", "avatar", "badge", "boolean", "checkbox", "color", "combobox", "date", "datetime-local", "document", "documents", "duration", "email", "field-array", "file", "files", "gdprConsent", "geopoint", "hidden", "iban", "image", "images", "map", "month", "multiselect", "number", "currency", "price", "password", "radio", "reference", "range", "rating", "reset", "richtext", "select", "submit", "switch", "tel", "text", "textarea", "time", "timestamp", "url", "week", "year"];

/**
 * @fileoverview Condition Types
 * @description Pure type definitions for the condition engine.
 * Runtime evaluation and builder logic live in @donotdev/utils.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/** Supported comparison operators */
type ConditionOperator = 'equals' | 'notEquals' | 'in' | 'notIn' | 'greaterThan' | 'lessThan' | 'greaterThanOrEqual' | 'lessThanOrEqual' | 'exists' | 'notExists' | 'contains';
/** A single condition: field + operator + value */
interface ConditionNode {
    readonly type: 'condition';
    readonly field: string;
    readonly operator: ConditionOperator;
    readonly value?: unknown;
}
/** Logical group of conditions */
interface ConditionGroup {
    readonly type: 'group';
    readonly logic: 'and' | 'or';
    readonly conditions: ReadonlyArray<ConditionExpression>;
}
/** A condition expression — the serializable data model for conditions */
type ConditionExpression = ConditionNode | ConditionGroup;
/** Result of evaluating all conditions for a field */
interface ConditionResult {
    /** Whether the field should be visible (default: true) */
    visible: boolean;
    /** Whether the field should be disabled (default: false) */
    disabled: boolean;
    /** Whether the field is required (default: false, overrides static validation.required) */
    required: boolean;
    /** Whether the field is readonly (default: false) */
    readonly: boolean;
}
/**
 * Structural interface satisfied by ConditionBuilder (defined in @donotdev/utils).
 * Allows types to reference builders without depending on the runtime class.
 */
interface ConditionBuilderLike {
    readonly expression: ConditionExpression;
}
/** Accepted condition input — either a raw expression or a ConditionBuilder */
type ConditionInput = ConditionExpression | ConditionBuilderLike;
/** Conditions that can be attached to a field */
interface ConditionalBehavior {
    /** Condition for field visibility — if false, field is hidden and excluded from validation */
    visible?: ConditionInput;
    /** Condition for field disabled state */
    disabled?: ConditionInput;
    /** Condition for dynamic required — evaluated at runtime */
    required?: ConditionInput;
    /** Condition for readonly state */
    readonly?: ConditionInput;
}

/**
 * @fileoverview Schema-Related Type Definitions
 * @description Types for schema validation using Valibot. Defines entity schemas, field types, and validation rules.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Visibility level for entity fields
 * Controls who can SEE a field - hierarchical (each level sees levels below)
 *
 * Hierarchy: guest < user < admin < super
 *
 * - 'guest': Everyone (even unauthenticated)
 * - 'user': Authenticated users (see guest + user fields)
 * - 'admin': Admins (see guest + user + admin fields)
 * - 'super': Super admins (see guest + user + admin + super fields)
 * - 'technical': System fields (admins+ only, shown as read-only in forms)
 * - 'hidden': Never exposed to client (passwords, tokens, API keys)
 *
 * Override with `editable` for write permissions.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type Visibility = (typeof VISIBILITY)[keyof typeof VISIBILITY];
/**
 * Editable level for entity fields
 * Controls who can MODIFY a field
 * - true: Anyone who can see the field
 * - false: Nobody (read-only, still shown in form)
 * - 'admin': Admin+ can edit (role hierarchy)
 * - 'super': Super only
 * - 'create-only': Editable on create, read-only after
 * - 'generated': DB-generated — hidden from forms, stripped from writes
 * - 'computed': UI-computed (derived from other fields) — hidden from forms, included in writes
 *
 * Custom role strings (e.g. future hierarchy keys) are accepted the same way as
 * {@link FieldType}: `(string & {})` keeps known literals distinguishable for
 * narrowing; plain `| string` would collapse to `boolean | string` and break
 * comparisons to `EDITABLE.GENERATED` / `EDITABLE.COMPUTED`.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type Editable = (typeof EDITABLE)[keyof typeof EDITABLE] | (string & {});
/**
 * Entity-level access configuration
 * Controls who can perform CRUD operations on the entity
 *
 * Uses role hierarchy: guest (0) < user (1) < admin (2) < super (3)
 * Higher roles inherit access to lower-level operations.
 *
 * @default DEFAULT_ENTITY_ACCESS (read: 'guest', create/update/delete: 'admin')
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface EntityAccessConfig {
    /** Minimum role required to create entities */
    create?: UserRole;
    /** Minimum role required to read entities (field visibility still applies) */
    read?: UserRole;
    /** Minimum role required to update entities */
    update?: UserRole;
    /** Minimum role required to delete entities */
    delete?: UserRole;
}
/** Type derived from DEFAULT_ENTITY_ACCESS for type safety */
type EntityAccessDefaults = typeof DEFAULT_ENTITY_ACCESS;
/**
 * Single condition for public read/update in Firestore rules.
 * Joined with && when publicCondition is an array.
 */
interface EntityOwnershipPublicCondition {
    field: string;
    op: string;
    value: string | boolean | number;
}
/**
 * Ownership configuration for stakeholder access (marketplace-style entities).
 * When set, drives Firestore rule condition generation, list/listCard query constraints,
 * and visibility: 'owner' field masking.
 *
 * @example
 * ```typescript
 * ownership: {
 *   ownerFields: ['providerId', 'customerId'],
 *   publicCondition: [
 *     { field: 'status', op: '==', value: 'available' },
 *     { field: 'isApproved', op: '==', value: true },
 *   ],
 * }
 * ```
 */
interface EntityOwnershipConfig {
    /** Document fields whose value is a user id (e.g. providerId, customerId) */
    ownerFields: string[];
    /** Conditions joined with && for "public" read (e.g. status == 'available') */
    publicCondition?: EntityOwnershipPublicCondition[];
}
/**
 * Supported field types for entities
 * These determine the UI components and validation rules used for each field
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FieldType = (typeof FIELD_TYPES)[number] | (string & {});
/**
 * Built-in field type union (same as FieldType). Used internally to distinguish
 * framework field types from custom types registered via registerFieldType().
 */
type BuiltInFieldType = (typeof FIELD_TYPES)[number];
/**
 * Map of custom field type names to their option shapes for `options.fieldSpecific`.
 * Augment this interface in your app so entity definitions get typed options for custom types.
 *
 * @example
 * ```ts
 * // In your app (e.g. types/crud.d.ts or next to your entity):
 * import '@donotdev/core';
 * declare module '@donotdev/core' {
 *   interface CustomFieldOptionsMap {
 *     'custom-address': { extractZipCode?: boolean };
 *     'repairOperations': { maxItems?: number };
 *   }
 * }
 * ```
 * Then in entity fields: `type: 'custom-address'`, `options: { fieldSpecific: { extractZipCode: true } }` is type-checked.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CustomFieldOptionsMap {
}
/**
 * Additional UI-specific options for field rendering
 * @template T - The field type (built-in or custom string). Custom types use CustomFieldOptionsMap for fieldSpecific.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UIFieldOptions<T extends string = FieldType> {
    /** The section under which this field should be grouped */
    section?: string;
    /** Placeholder text */
    placeholder?: string;
    /** Whether to show a clear button */
    clearable?: boolean;
    /** Additional classes to apply to the field */
    className?: string;
    /** Icon to show before the field */
    prefixIcon?: ComponentType;
    /** Icon to show after the field */
    suffixIcon?: ComponentType;
    /** Custom validation message overrides */
    messages?: {
        required?: string;
        pattern?: string;
        min?: string;
        max?: string;
        minLength?: string;
        maxLength?: string;
    };
    /** Step value for numeric inputs */
    step?: T extends 'number' | 'range' ? number : never;
    /**
     * i18n key for display formatting. Replaces the raw value in lists/cards/display views.
     * The formatter calls `t(displayKey, { value })`. Supports i18next array-key fallback.
     * Use `{{value}}` in key names for dynamic lookup (interpolated before `t()` call).
     *
     * @example Single key: `displayKey: 'fields.size_display'` → locale `"{{value}}m²"` → "20m²"
     * @example Array fallback: `displayKey: ['floor_{{value}}', 'fields.floor_display']`
     *   → tries `floor_4`, falls back to `fields.floor_display`: `"{{value}}th floor"` → "4th floor"
     */
    displayKey?: string | string[];
    /**
     * Custom display value resolver. Overrides type formatter and displayKey for display views.
     * Receives the field value, the full item, and the translation function —
     * useful for cross-field conditional display with i18n.
     * Return `null` to hide the field for that item. Return a string to display it.
     *
     * @example
     * ```typescript
     * // Hide date for reserved/signed, show "Available" for past dates
     * displayValue: (value, item, t) => {
     *   if (item.status === 'reserved' || item.status === 'signed') return null;
     *   return value <= today ? t('status.available_now') : String(value);
     * }
     * ```
     */
    displayValue?: (value: unknown, item: Record<string, unknown>, t: (key: string, options?: Record<string, unknown>) => string) => string | null;
    /** Whether to show value label for range inputs */
    showValue?: T extends 'range' ? boolean : never;
    /** Field specific options based on field type. Custom types: augment CustomFieldOptionsMap. */
    fieldSpecific?: T extends keyof CustomFieldOptionsMap ? CustomFieldOptionsMap[T] : T extends 'file' | 'image' | 'files' | 'images' | 'document' | 'documents' ? {
        /** File types to accept (e.g., 'image/*', '.pdf') */
        accept?: string;
        /** Maximum file size in bytes */
        maxSize?: number;
        /** Whether to allow multiple files */
        multiple?: boolean;
        /** Storage path prefix for uploads (e.g., 'apartments') */
        storagePath?: string;
    } : T extends 'geopoint' ? {
        /** Default zoom level for map */
        defaultZoom?: number;
        /** Default center position for map */
        defaultCenter?: {
            lat: number;
            lng: number;
        };
    } : T extends 'map' ? {
        /** Label for the key input */
        keyLabel?: string;
        /** Label for the value input */
        valueLabel?: string;
        /** Label for the add button */
        addLabel?: string;
    } : T extends 'reference' ? {
        /** Field to display from the referenced entity */
        displayField?: string;
        /** Multiple fields to join as label (e.g. ['first_name', 'last_name'] → "John Doe") */
        labelFields?: string[];
        /** Fields to search in the referenced entity */
        searchFields?: string[];
        /** Maximum number of items to preload */
        preloadLimit?: number;
    } : T extends 'tel' ? {
        /** Default country code */
        defaultCountry?: string;
        /** Whether to show country flags */
        showFlags?: boolean;
        /** Preferred country codes to show at the top of the list (e.g., ['FR', 'US', 'GB']) */
        preferredCountries?: string[];
        /** Custom list of country codes to show (if provided, only these countries are shown) */
        countries?: string[];
    } : T extends 'address' ? {
        /**
         * Whether to enable Google Maps autocomplete (default: false)
         * Requires env var: VITE_GOOGLE_MAPS_API_KEY (Vite) or NEXT_PUBLIC_GOOGLE_MAPS_API_KEY (Next.js)
         */
        enableGoogleMaps?: boolean;
        /** Whether to extract district code for Paris addresses */
        extractDistrictCode?: boolean;
    } : T extends 'combobox' ? {
        /** Enable creating new values by typing */
        creatable?: boolean;
    } : T extends 'switch' ? {
        /** Label shown when switch is off/unchecked */
        uncheckedLabel?: string;
        /** Label shown when switch is on/checked */
        checkedLabel?: string;
        /** Value stored when switch is off (default: false) */
        uncheckedValue?: string | boolean;
        /** Value stored when switch is on (default: true) */
        checkedValue?: string | boolean;
    } : T extends 'gdprConsent' ? {
        /** Path to privacy policy page (default: '/legal/privacy') */
        privacyPolicyPath?: string;
        /** Path to terms of use page (default: '/legal/terms') */
        termsPath?: string;
    } : Record<string, unknown>;
}
/**
 * Picture type for image fields
 * Represents uploaded image with full and thumbnail URLs
 */
interface Picture {
    fullUrl: string;
    thumbUrl: string;
}
/**
 * FileAsset type for generic file uploads (documents, any files)
 * Used by FileFieldComponent and DocumentFieldComponent
 */
interface FileAsset {
    /** Download URL for the file */
    url: string;
    /** Original filename */
    filename: string;
    /** File size in bytes */
    size: number;
    /** MIME type (e.g., 'application/pdf') */
    mimeType?: string;
    /** ISO timestamp when uploaded */
    uploadedAt?: string;
}
/**
 * Maps field types to their corresponding TypeScript types
 * Used for type-safe form handling
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FieldTypeToValue = {
    address: {
        formatted_address: string;
        latitude: number;
        longitude: number;
        [key: string]: any;
    };
    array: any[];
    avatar: string;
    badge: string;
    boolean: boolean;
    checkbox: boolean;
    combobox: string;
    color: string;
    date: string;
    'datetime-local': string;
    document: FileAsset | null;
    documents: FileAsset[];
    email: string;
    'field-array': Record<string, unknown>[];
    file: FileAsset | null;
    files: FileAsset[];
    geopoint: {
        lat: number;
        lng: number;
    };
    hidden: string;
    iban: string;
    image: Picture | null;
    images: Picture[];
    map: Record<string, any>;
    month: string;
    multiselect: string[];
    number: number;
    price: {
        amount: number;
        currency?: string;
        vatIncluded?: boolean;
        discountPercent?: number;
    };
    password: string;
    radio: string;
    reference: string;
    range: number;
    reset: never;
    select: string;
    submit: never;
    tel: string;
    text: string;
    textarea: string;
    time: string;
    timestamp: string;
    switch: string | boolean;
    url: string;
    week: string;
    year: number;
};
/**
 * Gets the value type for a specific field type
 * @template T - The field type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ValueTypeForField<T extends string> = T extends keyof FieldTypeToValue ? FieldTypeToValue[T] : unknown;
/**
 * Any valid field value - includes built-in types plus custom registered types
 * Uses `unknown` since consumers can register custom field types via RegisterFieldType
 */
type AnyFieldValue = unknown;
/**
 * Entity record type - a record where values are valid field values
 * Accepts unknown since consumers can register custom field types
 */
type EntityRecord = Record<string, AnyFieldValue>;
/**
 * Enhanced validation rules with type checking
 * @template T - The field type
 *
 * @example
 * ```typescript
 * // Select field with dropdown options
 * validation: {
 *   required: true,
 *   options: [
 *     { value: 'active', label: 'Active' },
 *     { value: 'inactive', label: 'Inactive' }
 *   ]
 * }
 *
 * // Text field with length validation
 * validation: {
 *   required: true,
 *   minLength: 3,
 *   maxLength: 100
 * }
 *
 * // Number field with range validation
 * validation: {
 *   required: true,
 *   min: 0,
 *   max: 1000
 * }
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ValidationRules<T extends string = FieldType> {
    /** Whether the field is required */
    required?: boolean;
    /** Minimum value (for number fields) */
    min?: T extends 'number' | 'range' | 'year' ? number : never;
    /** Maximum value (for number fields) */
    max?: T extends 'number' | 'range' | 'year' ? number : never;
    /** Minimum length (for text fields) */
    minLength?: T extends 'text' | 'textarea' | 'password' | 'email' | 'url' | 'tel' | 'iban' ? number : never;
    /** Maximum length (for text fields) */
    maxLength?: T extends 'text' | 'textarea' | 'password' | 'email' | 'url' | 'tel' | 'iban' ? number : never;
    /** Regex pattern (for text fields) */
    pattern?: T extends 'text' | 'textarea' | 'password' | 'email' | 'url' | 'tel' | 'iban' ? string : never;
    /**
     * Options for select, multiselect, and radio fields.
     * Can be:
     * - An array of option objects
     * - A function that returns an array (receives form values for dynamic options)
     *
     * For year fields, use `type: 'year'`:
     * ```typescript
     * year: {
     *   type: 'year',
     *   visibility: 'guest',
     *   validation: {
     *     required: true,
     *     min: 1900,  // Optional: defaults to 1900
     *     max: 2100   // Optional: defaults to current year + 10
     *   }
     * }
     * ```
     *
     * @example
     * ```typescript
     * // Static array
     * options: [
     *   { value: 'active', label: 'Active' },
     *   { value: 'inactive', label: 'Inactive' }
     * ]
     *
     * // Dynamic function (depends on other field values)
     * options: (formValues) => {
     *   return getModelsForMake(formValues.make);
     * }
     * ```
     */
    options?: T extends 'select' | 'multiselect' | 'radio' | 'combobox' ? Array<{
        value: string;
        label: string;
    }> | ((formValues?: Record<string, any>) => Array<{
        value: string;
        label: string;
    }>) : never;
    /** Collection name for reference fields */
    reference?: T extends 'reference' ? string : never;
    /** Whether the field is nullable */
    nullable?: boolean;
    /**
     * Custom Valibot schema for this field
     *
     * When provided, this schema is used directly instead of the registry lookup.
     * This makes the entity the single source of truth for custom field schemas,
     * working everywhere (client + server) without separate registrations.
     *
     * @example
     * ```typescript
     * repairs: {
     *   type: 'repairOperations',
     *   visibility: 'admin',
     *   validation: {
     *     schema: v.array(v.object({
     *       operation: v.string(),
     *       cost: v.number()
     *     }))
     *   }
     * }
     * ```
     */
    schema?: v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>;
}
/**
 * Form step configuration for multi-step forms
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FormStep {
    /** Step title displayed in navigation */
    title: string;
    /** Step description (optional) */
    description?: string;
    /** Fields to include in this step */
    fields: string[];
    /** Whether this step is required */
    required?: boolean;
    /** Custom validation for this step */
    validation?: {
        /** Custom validation function */
        validate?: (data: any) => boolean | string;
        /** Error message if validation fails */
        message?: string;
    };
}
/**
 * Condition for dynamic field visibility
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FieldCondition {
    /** Field name to check */
    field: string;
    /** Comparison operator */
    operator: 'equals' | 'not-equals' | 'contains' | 'greater-than' | 'less-than' | 'exists' | 'not-exists';
    /** Value to compare against */
    value?: any;
    /** For complex conditions, use a function */
    evaluate?: (formData: any) => boolean;
}
/**
 * Dynamic form rule for showing/hiding fields
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface DynamicFormRule {
    /** Condition that triggers this rule */
    condition: FieldCondition | FieldCondition[];
    /** Fields to show when condition is met */
    showFields?: string[];
    /** Fields to hide when condition is met */
    hideFields?: string[];
    /** Fields to disable when condition is met */
    disableFields?: string[];
    /** Fields to enable when condition is met */
    enableFields?: string[];
}
/**
 * Form configuration for advanced form features
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FormConfig {
    /** Form type */
    type?: 'single' | 'multi-step' | 'dynamic' | 'wizard';
    /** Steps for multi-step forms */
    steps?: FormStep[];
    /** Dynamic field rules */
    rules?: DynamicFormRule[];
    /** Whether to persist form state (auto-save drafts) */
    persist?: boolean;
    /** Persistence configuration */
    persistence?: {
        /** Storage key prefix */
        key?: string;
        /** Auto-save interval in milliseconds */
        autoSaveInterval?: number;
        /** Whether to show save indicator */
        showSaveIndicator?: boolean;
    };
    /** Form layout configuration */
    layout?: {
        /** Number of columns for field layout */
        columns?: 1 | 2 | 3;
        /** Whether to show field labels */
        showLabels?: boolean;
        /** Whether to show field hints */
        showHints?: boolean;
        /** Custom CSS classes */
        className?: string;
    };
    /** Form behavior configuration */
    behavior?: {
        /** Whether to show progress indicator */
        showProgress?: boolean;
        /** Whether to allow step navigation */
        allowStepNavigation?: boolean;
        /** Whether to validate on step change */
        validateOnStepChange?: boolean;
        /** Whether to show step numbers */
        showStepNumbers?: boolean;
    };
}
/**
 * Definition of a single entity field
 * @template T - The field type for type-safe validation and value inference
 *
 * @example
 * ```typescript
 * // Text field - TypeScript knows value is string
 * name: {
 *   type: 'text',
 *   visibility: 'user',
 *   validation: { required: true, minLength: 3 }
 * }
 *
 * // Select field with dropdown options
 * status: {
 *   type: 'select',
 *   visibility: 'user',
 *   validation: {
 *     required: true,
 *     options: [
 *       { value: 'active', label: 'Active' },
 *       { value: 'inactive', label: 'Inactive' }
 *     ]
 *   }
 * }
 * ```
 *
 * **Note:** For `select`, `multiselect`, and `radio` fields, dropdown options must be defined in `validation.options` as an array of `{ value: string, label: string }` objects.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface EntityField<T extends string = FieldType> {
    /** Field identifier - required for form binding */
    name: string;
    /** The field type, which determines the UI component and validation */
    type: T;
    /**
     * Who can SEE this field
     * - 'guest': Everyone (even unauthenticated)
     * - 'user': Authenticated users only (users see both guest and user fields)
     * - 'admin': Admins only
     * - 'technical': Internal/system fields (shown as read-only in edit forms)
     * - 'hidden': Never shown in UI, only exists in DB (passwords, tokens, API keys)
     */
    visibility: Visibility;
    /**
     * Who can MODIFY this field
     * - true: Anyone who can see the field (default)
     * - false: Nobody (read-only display)
     * - 'admin': Only admins can edit
     * - 'create-only': Editable on create, read-only after
     */
    editable?: Editable;
    /** Validation rules for this field. For select/multiselect/radio fields, include `options` array here. */
    validation?: ValidationRules<T>;
    /** Whether the field is internationalized */
    i18n?: boolean;
    /** Display label for the field */
    label: string;
    /** Hint text to display under the field */
    hint?: string;
    /** Field dependencies for dynamic forms */
    dependsOn?: {
        /** Field name this field depends on */
        field: string;
        /** Value that should trigger this field to show */
        value?: ValueTypeForField<FieldType>;
        /** Custom condition function */
        condition?: (formData: Record<string, unknown>) => boolean;
    };
    /** Field grouping for layout */
    group?: {
        /** Group name */
        name: string;
        /** Group title */
        title?: string;
        /** Group description */
        description?: string;
        /** Whether group is collapsible */
        collapsible?: boolean;
        /** Whether group is collapsed by default */
        collapsed?: boolean;
    };
    /**
     * Dynamic conditions for field behavior based on other field values.
     * Controls visibility, disabled, required, and readonly states at runtime.
     *
     * @example
     * ```typescript
     * conditions: {
     *   visible: when('productType').equals('car'),
     *   required: when('productType').equals('car'),
     * }
     * ```
     */
    conditions?: ConditionalBehavior;
    /** UI-specific configuration for field rendering */
    options?: UIFieldOptions<T>;
}
/**
 * Base fields that all entities should have
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseEntityFields {
    /** Unique identifier for the entity */
    id: EntityField<'text'>;
    /** When the entity was created */
    createdAt: EntityField<'timestamp'>;
    /** When the entity was last updated */
    updatedAt: EntityField<'timestamp'>;
    /** Who created the entity */
    createdById: EntityField<'reference'>;
    /** Who last updated the entity */
    updatedById: EntityField<'reference'>;
    /**
     * Publication status for draft/publish/delete workflow
     * - 'draft': Document is incomplete, hidden from non-admin
     * - 'available': Document is published and visible (default)
     * - 'deleted': Soft-deleted, hidden from non-admin
     * - Consumer can extend with additional statuses (e.g., 'reserved', 'sold')
     */
    status: EntityField<'select'>;
}
/**
 * Consumer `fields` merged with {@link BaseEntityFields} — same keys {@link defineEntity} returns.
 *
 * @version 0.1.0
 * @since 0.2.0
 */
type MergedEntityFieldMap<F extends Record<string, EntityField>> = F & BaseEntityFields;
/**
 * Merged field map with `readonly` stripped from keys — improves assignability of
 * `defineEntity` results to widened {@link AnyEntity} props.
 *
 * @version 0.1.0
 * @since 0.2.0
 */
type MutableMergedEntityFieldMap<F extends Record<string, EntityField>> = {
    -readonly [K in keyof MergedEntityFieldMap<F>]: MergedEntityFieldMap<F>[K];
};
/**
 * Default merged field map when an entity is not parameterized with a literal field map.
 *
 * @version 0.1.0
 * @since 0.2.0
 */
type EntityFieldMapDefault = Record<string, EntityField> & BaseEntityFields;
/**
 * CRUD/cache document row inferred from an entity `fields` map (SSOT with `defineEntity` literals).
 * Intersects {@link Record} so rows satisfy `T extends Record<string, unknown>` (bulk, PII, adapters).
 *
 * @version 0.1.0
 * @since 0.2.0
 */
type EntityRowFromFields<F extends Record<string, EntityField>> = {
    [K in keyof F]: F[K] extends EntityField<infer FT> ? FT extends keyof FieldTypeToValue ? FieldTypeToValue[FT] : unknown : unknown;
} & Record<string, unknown>;
/**
 * Unique key constraint definition for entity deduplication
 * Enables automatic checking for duplicates on create/update operations
 *
 * @example
 * ```typescript
 * // Single field unique key with findOrCreate
 * uniqueKeys: [{ fields: ['email'], findOrCreate: true }]
 *
 * // Composite unique key
 * uniqueKeys: [{ fields: ['vin', 'make'], skipForDrafts: true }]
 *
 * // Multiple keys (OR logic - either can identify)
 * uniqueKeys: [
 *   { fields: ['email'], findOrCreate: true },
 *   { fields: ['phone'], findOrCreate: true }
 * ]
 * ```
 *
 * @version 0.1.0
 * @since 0.0.5
 * @author AMBROISE PARK Consulting
 */
interface UniqueKeyDefinition {
    /** Field names that together form the unique key (single or composite) */
    fields: string[];
    /** Custom error message when duplicate is found */
    errorMessage?: string;
    /** Skip validation for draft documents (default: false) */
    skipForDrafts?: boolean;
    /**
     * Return existing document instead of throwing error on duplicate (default: false)
     * When true, create operations will return the existing document if a match is found
     */
    findOrCreate?: boolean;
}
/**
 * SOC2 security configuration for an entity.
 * Zero-config path: omit this entirely for MVP — add it when going to production/SOC2 audit.
 *
 * When a `SecurityContext` is passed to `CrudService`, these options control:
 * - Which fields are encrypted at rest (PII)
 * - Whether CRUD mutations are audit-logged (default: true)
 * - Entity-level rate limit overrides
 * - MFA requirement for a given role tier
 * - Data retention for automated purge scheduling
 *
 * @example
 * ```typescript
 * security: {
 *   piiFields: ['email', 'phone', 'ssn'],
 *   requireMfa: 'admin',
 *   retention: { days: 365 },
 * }
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SecurityEntityConfig {
    /**
     * Field names to encrypt at rest using AES-256-GCM.
     * Requires `piiSecret` in `DndevSecurityConfig`.
     * Only string field values are encrypted; other types are skipped silently.
     */
    piiFields?: string[];
    /**
     * Whether to emit audit log entries for all CRUD mutations on this entity.
     * @default true (when SecurityContext is provided)
     */
    auditLog?: boolean;
    /**
     * Override rate limits for this entity (uses global defaults if omitted).
     */
    rateLimit?: {
        writes?: number;
        reads?: number;
        windowSeconds?: number;
    };
    /**
     * Enforce MFA for users at or above this role attempting mutations.
     * The adapter must verify MFA status from the auth token/session.
     */
    requireMfa?: UserRole;
    /**
     * Data retention policy — documents older than `days` are flagged for purge.
     * Integrate with `PrivacyManager.shouldPurge()` in a scheduled function.
     */
    retention?: {
        days: number;
    };
}
/**
 * Multi-tenancy scope configuration for entities
 * Enables automatic scoping of data by tenant/company/workspace
 *
 * @example
 * ```typescript
 * const clientEntity = defineEntity({
 *   name: 'Client',
 *   collection: 'clients',
 *   scope: { field: 'companyId', provider: 'company' },
 *   fields: { ... } // No need to manually define companyId
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
interface ScopeConfig {
    /**
     * Field name that stores the scope ID (e.g., 'companyId', 'tenantId', 'workspaceId')
     * This field will be auto-added to the entity with type 'reference'
     */
    field: string;
    /**
     * Name of the scope provider registered with registerScopeProvider()
     * The provider function returns the current scope ID from app state
     * @example 'company', 'tenant', 'workspace'
     */
    provider: string;
    /**
     * Collection being referenced (optional, defaults to field name without 'Id' suffix + 's')
     * @example 'companies' for field 'companyId'
     */
    collection?: string;
}
/**
 * Slot-based card layout for listCardFields.
 * Maps entity field names to card slots (title, subtitle, content, footer).
 */
interface ListCardLayout {
    /** Fields rendered as the card title (joined with titleSeparator) */
    title?: string[];
    /**
     * Separator used to join multiple title field values.
     * @default ' '
     * @example `titleSeparator: ' - '` → "Paris 20e arr. - 20m²"
     */
    titleSeparator?: string;
    /** Fields rendered as the card subtitle */
    subtitle?: string[];
    /** Fields rendered in the card body (supports images) */
    content?: string[];
    /** Fields rendered in the card footer */
    footer?: string[];
}
/**
 * Definition of a business entity without base fields
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BusinessEntity<out F extends Record<string, EntityField> = Record<string, EntityField>> {
    /** Name of the entity */
    name: string;
    /** Firestore collection name */
    collection: string;
    /**
     * i18n namespace for translations (defaults to `entity-${name.toLowerCase()}`)
     * @example "entity-car", "entity-product"
     * @default `entity-${name.toLowerCase()}`
     */
    namespace?: string;
    /**
     * Multi-tenancy scope configuration (optional)
     * When set, the scope field is auto-added and CRUD operations auto-inject/filter by scope
     *
     * @example
     * ```typescript
     * scope: { field: 'companyId', provider: 'company' }
     * ```
     */
    scope?: ScopeConfig;
    /**
     * Stakeholder ownership configuration (optional).
     * When set, drives Firestore rule condition (read/update), list/listCard query constraints,
     * and visibility: 'owner' field masking. Use for marketplace-style entities (e.g. schedules:
     * public when available, private to partner/customer when booked).
     *
     * @example
     * ```typescript
     * ownership: {
     *   ownerFields: ['providerId', 'customerId'],
     *   publicCondition: [{ field: 'status', op: '==', value: 'available' }],
     * }
     * ```
     */
    ownership?: EntityOwnershipConfig;
    /** Field definitions - name and label are required */
    fields: F;
    /** Form configuration for advanced forms */
    form?: FormConfig;
    /**
     * Fields to include in admin list responses (optional).
     * Used by EntityList for optimized admin table queries.
     * If not specified, all visible fields are returned.
     * 'id' is always included automatically.
     *
     * @example
     * ```typescript
     * listFields: ['id', 'make', 'model', 'status', 'createdAt']
     * ```
     */
    listFields?: string[];
    /**
     * Fields to include in public card list responses.
     * Accepts a flat array (auto-layout) or a slot-based `ListCardLayout` object.
     *
     * Each field value is formatted via `formatValue()` using its registered display formatter.
     * For `'number'` fields, use `unit` and `suffix` field options for rich display — no custom
     * type needed:
     * - `unit: 'm²'` → "20m²" (appended directly, no space)
     * - `suffix: 'fields.rent_suffix'` → "700€ charges comprises" (i18n key, space-separated)
     *
     * Use `titleSeparator` in `ListCardLayout` to control how multiple title fields are joined
     * (default `' '`).
     *
     * @example
     * ```typescript
     * // Flat — auto-slots first field as title, rest as content
     * listCardFields: ['images', 'make', 'price', 'year']
     *
     * // Slot-based — explicit card layout with separator
     * listCardFields: {
     *   titleSeparator: ' - ',
     *   title: ['district_code', 'size'],   // e.g. "Paris 20e arr. - 20m²"
     *   subtitle: ['rent'],                  // e.g. "700€ charges comprises"
     *   content: ['pictures', 'nearby_stations'],
     * }
     * ```
     */
    listCardFields?: string[] | ListCardLayout;
    /**
     * Entity-level access control configuration.
     * Defines minimum role required for each CRUD operation.
     * Uses role hierarchy: guest (0) < user (1) < admin (2) < super (3)
     *
     * Defaults (via defineEntity):
     * - read: 'guest' (public read, field visibility handles sensitive data)
     * - create/update/delete: 'admin'
     *
     * @example
     * ```typescript
     * // Public inquiry form
     * access: { create: 'guest', read: 'admin' }
     *
     * // Members-only content
     * access: { read: 'user' }
     * ```
     */
    access?: EntityAccessConfig;
    /**
     * Unique key constraints for deduplication
     * Checked during create/update operations
     *
     * - Single field: `[{ fields: ['email'] }]`
     * - Composite: `[{ fields: ['vin', 'make'] }]`
     * - Multiple keys (OR): `[{ fields: ['email'] }, { fields: ['phone'] }]`
     *
     * @example
     * ```typescript
     * // Customer: email OR phone identifies (findOrCreate behavior)
     * uniqueKeys: [
     *   { fields: ['email'], findOrCreate: true },
     *   { fields: ['phone'], findOrCreate: true }
     * ]
     *
     * // Car: VIN is unique, skip for drafts
     * uniqueKeys: [{ fields: ['vin'], skipForDrafts: true }]
     * ```
     */
    uniqueKeys?: UniqueKeyDefinition[];
    /**
     * SOC2 security configuration for this entity (optional — zero-config MVP path).
     * When a `SecurityContext` is provided to `CrudService`, these settings control
     * PII encryption, audit logging, rate limits, MFA enforcement, and retention.
     *
     * @example
     * ```typescript
     * security: {
     *   piiFields: ['email', 'phone'],
     *   requireMfa: 'admin',
     *   retention: { days: 365 },
     * }
     * ```
     */
    security?: SecurityEntityConfig;
    /**
     * Client-side search config for `useCrudList`/`useCrudCardList` `searchQuery` option.
     * If omitted, all text-like visible fields are searched automatically.
     *
     * @example
     * ```typescript
     * search: { fields: ['name', 'description', 'sku'] }
     * ```
     */
    search?: {
        fields?: string[];
    };
    /**
     * Default client-side sort for list hooks.
     * Applied when no explicit `clientSort` option is passed and no `orderBy` in `queryOptions`.
     * Pass `clientSort: null` in hook options to disable.
     *
     * @example
     * ```typescript
     * defaultSort: { field: 'createdAt', direction: 'desc' }
     * ```
     */
    defaultSort?: {
        field: string;
        direction?: 'asc' | 'desc';
    };
}
/**
 * Complete entity definition including base fields
 * Created by defineEntity() which merges defaults
 *
 * Extends BusinessEntity but overrides optional properties to required:
 * - namespace: always computed (defaults to `entity-${name.toLowerCase()}`)
 * - access: always merged with defaults
 * - fields: includes base fields (id, createdAt, etc.)
 * - scope: preserved if provided (for multi-tenancy)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface Entity<out F extends Record<string, EntityField> = EntityFieldMapDefault> extends Omit<BusinessEntity<F>, 'access' | 'namespace'> {
    /** Field definitions including base fields */
    fields: F;
    /** Access configuration with defaults applied (always present after defineEntity) */
    access: Required<EntityAccessConfig>;
    /** i18n namespace for translations (always present after defineEntity, defaults to `entity-${name.toLowerCase()}`) */
    namespace: string;
    /** Multi-tenancy scope configuration (preserved from BusinessEntity if provided) */
    scope?: ScopeConfig;
}
/**
 * Document row type for an entity from {@link defineEntity} — use with `useCrud`, `bulk`, and list hooks.
 *
 * @version 0.1.0
 * @since 0.2.0
 */
/**
 * Widened entity type for props and APIs that accept any `defineEntity()` result
 * without casting to default {@link Entity}.
 *
 * @version 0.1.0
 * @since 0.2.0
 */
type AnyEntity = Entity<Record<string, EntityField>>;
/**
 * Inferred document row for an entity. Always includes `id` so rows are valid for
 * lists, keys, and `Record<string, any>`-shaped component props even when `E` is
 * the widened {@link AnyEntity} (`fields` is only a string index signature).
 */
type InferEntityRow<E extends AnyEntity> = EntityRowFromFields<E['fields']> & {
    id: string;
};
/**
 * Unified metadata structure for all schemas (CRUD, Functions, etc.)
 * Consolidates different metadata patterns into one DRY interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SchemaMetadata {
    /** Firestore collection name */
    collection: string;
    /** Entity name (for CRUD schemas) */
    entity?: string;
    /** Form configuration (for CRUD schemas) */
    form?: FormConfig;
    /** Fields that should be unique within the collection (for function validation) */
    uniqueFields?: Array<{
        field: string;
        errorMessage?: string;
    }>;
    /**
     * Unique key constraints from entity definition
     * Used by backend CRUD functions for deduplication
     */
    uniqueKeys?: UniqueKeyDefinition[];
    /** Custom validation function (for function validation) */
    customValidate?: (data: Record<string, any>, operation: 'create' | 'update') => Promise<void>;
}
/**
 * Unified schema type that includes DoNotDev metadata
 * @template T - The entity/data type
 *
 * Unified schema type for all DoNotDev schemas
 * Uses Valibot's BaseSchema for validation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type dndevSchema<T> = v.BaseSchema<unknown, T, v.BaseIssue<unknown>> & {
    metadata: SchemaMetadata;
};
/**
 * Interface for database uniqueness validation
 * This abstraction allows for plugging in any database implementation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UniqueConstraintValidator {
    /**
     * Checks if a value would cause a duplicate in a given collection
     * @param collection - The collection/table name
     * @param field - The field name to check
     * @param value - The field value to check for uniqueness
     * @param currentDocId - The current document ID (for updates)
     * @returns Whether a duplicate exists
     */
    checkDuplicate: (collection: string, field: string, value: any, currentDocId?: string) => Promise<boolean>;
}
/**
 * Schema for creating an entity
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const createEntitySchema: v.ObjectSchema<{
    readonly collection: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Collection name is required">]>;
    readonly data: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    readonly idempotencyKey: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/**
 * Schema for getting an entity
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const getEntitySchema: v.ObjectSchema<{
    readonly collection: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Collection name is required">]>;
    readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Entity ID is required">]>;
}, undefined>;
/**
 * Schema for updating an entity
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const updateEntitySchema: v.ObjectSchema<{
    readonly collection: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Collection name is required">]>;
    readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Entity ID is required">]>;
    readonly data: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    readonly merge: v.OptionalSchema<v.BooleanSchema<undefined>, false>;
}, undefined>;
/**
 * Schema for deleting an entity
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const deleteEntitySchema: v.ObjectSchema<{
    readonly collection: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Collection name is required">]>;
    readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Entity ID is required">]>;
}, undefined>;
/**
 * Schema for listing entities.
 *
 * Default limit is **1000** (server-enforced max: 1000).
 * For collections larger than 1000 items, use server-side pagination
 * (`pagination='server'` on EntityList, or cursor-based `startAfter` in hooks).
 *
 * @example
 * // Fetch up to 1000 items (default)
 * { collection: 'products' }
 *
 * @example
 * // Fetch 200 items
 * { collection: 'products', limit: 200 }
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const listEntitiesSchema: v.ObjectSchema<{
    readonly collection: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Collection name is required">]>;
    readonly limit: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 1, undefined>, v.MaxValueAction<number, 1000, undefined>]>, 1000>;
    readonly offset: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, 0>;
    readonly orderBy: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly orderDirection: v.OptionalSchema<v.PicklistSchema<["asc", "desc"], undefined>, "desc">;
    readonly where: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
        readonly field: v.StringSchema<undefined>;
        readonly operator: v.PicklistSchema<["==", "!=", "<", "<=", ">", ">=", "array-contains", "in", "not-in"], undefined>;
        readonly value: v.UnknownSchema;
    }, undefined>, undefined>, undefined>;
}, undefined>;
/**
 * Create entity request type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CreateEntityRequest = v.InferOutput<typeof createEntitySchema>;
/**
 * Get entity request type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type GetEntityRequest = v.InferOutput<typeof getEntitySchema>;
/**
 * Update entity request type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type UpdateEntityRequest = v.InferOutput<typeof updateEntitySchema>;
/**
 * Delete entity request type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type DeleteEntityRequest = v.InferOutput<typeof deleteEntitySchema>;
/**
 * List entities request type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ListEntitiesRequest = v.InferOutput<typeof listEntitiesSchema>;
/**
 * Create entity response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CreateEntityResponse {
    success: boolean;
    id: string;
    data: Record<string, any>;
}
/**
 * Get entity response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface GetEntityResponse {
    success: boolean;
    data: Record<string, any> | null;
}
/**
 * Update entity response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UpdateEntityResponse {
    success: boolean;
    id: string;
    data: Record<string, any>;
}
/**
 * Delete entity response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface DeleteEntityResponse {
    success: boolean;
    id: string;
}
/**
 * List entities response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ListEntitiesResponse {
    success: boolean;
    data: Record<string, any>[];
    total: number;
    hasMore: boolean;
}

/**
 * @fileoverview CRUD Types
 * @description Type definitions for CRUD domain. Defines entity types, field types, and CRUD-related interfaces.
 * Uses unified FeatureStatus enum for feature state management.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Payload for create flows (`add`, bulk `inserts`) before the document has a
 * stable `id` (server- or client-generated). Matches runtime: optimistic add
 * mints a temp id; the create schema validates this shape.
 *
 * @version 0.1.0
 * @since 0.2.0
 */
type CrudCreateInput<T> = T extends Record<string, unknown> ? Omit<T, 'id'> : Record<string, unknown>;
/**
 * CRUD API type - complete interface for useCrud hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CrudAPI<T = unknown> {
    /**
     * Unified feature status - single source of truth for CRUD state.
     * - `initializing`: CRUD is loading/initializing
     * - `ready`: CRUD fully operational
     * - `degraded`: CRUD unavailable (feature not installed/consent not given)
     * - `error`: CRUD encountered error
     */
    status: FeatureStatus;
    /** Current data (from get/subscribe) */
    data: T | null;
    /** Loading state for async operations */
    loading: boolean;
    /** Last error encountered */
    error: Error | null;
    /** Fetch single document by ID */
    get: (id: string) => Promise<T | null>;
    /** Set/replace document by ID */
    set: (id: string, data: T, options?: {
        showSuccessToast?: boolean;
    }) => Promise<void>;
    /** Partial update document by ID */
    update: (id: string, data: Partial<T>, options?: {
        showSuccessToast?: boolean;
    }) => Promise<void>;
    /** Delete document by ID */
    delete: (id: string, options?: {
        showSuccessToast?: boolean;
    }) => Promise<void>;
    /** Add new document (auto-generated ID) */
    add: (data: CrudCreateInput<T>, options?: {
        showSuccessToast?: boolean;
    }) => Promise<string>;
    /** Query collection with filters */
    query: (options: QueryOptions) => Promise<T[]>;
    /** Subscribe to document changes */
    subscribe: (id: string, callback: (data: T | null, error?: Error) => void) => () => void;
    /** Subscribe to collection changes */
    subscribeToCollection: (options: QueryOptions, callback: (data: T[], error?: Error) => void) => () => void;
    /** Invalidate cache for this collection (TanStack Query) */
    invalidate: () => Promise<void>;
    /** Whether CRUD is available and operational */
    isAvailable: boolean;
    /**
     * Cross-collection atomic bulk write. One optimistic pass, one toast,
     * coordinated rollback. Batches with `dependsOn` run after their
     * dependencies; independent batches run in parallel.
     */
    bulkAcross?: (batches: BulkAcrossBatch[], options?: {
        showSuccessToast?: boolean;
    }) => Promise<BulkAcrossResult>;
}
/**
 * Base props for entity templates
 * @template T - The form values type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface EntityTemplateProps<T extends FieldValues> {
    /** The DoNotDev schema for the entity */
    schema: dndevSchema<T>;
    /** Optional overrides for field configuration */
    fieldOverrides?: Partial<Record<keyof T, Partial<EntityField>>>;
}
/**
 * Column definition for list views
 * @template T - The item type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ColumnDef<T extends FieldValues> {
    /** Key in the data object */
    key: keyof T;
    /** Display label */
    label: string;
    /** Optional custom render function */
    render?: (value: T[keyof T], row: T) => ReactNode;
}
/**
 * Input shape for a bulk CRUD operation. All three fields are optional — callers
 * include only the buckets they need. Items are processed in input order per
 * bucket and returned in the same order in {@link BulkResult}.
 *
 * Semantics (enforced by the service, not the adapter):
 * - Atomic: all ops succeed or none do.
 * - Collision rejection: an id appearing in both `updates` and `deletes`, or both
 *   `inserts` and `updates`, fails up-front with {@link BulkCollisionError}.
 * - Empty bulk (`{}`) is a no-op that returns a zeroed {@link BulkResult}
 *   without hitting the adapter.
 *
 * @template T - Entity type for the collection. Must be an object so PII
 *   encryption, cache merging and adapter mapping can treat each row as a
 *   `Record<string, unknown>`.
 *
 * @example
 * const ops: BulkOperations<Event> = {
 *   inserts: [{ title: 'A' }, { title: 'B' }],
 *   updates: [{ id: 'e1', patch: { title: 'renamed' } }],
 *   deletes: ['e2', 'e3'],
 * };
 *
 * @version 0.1.0
 * @since 0.2.0
 * @author AMBROISE PARK Consulting
 */
interface BulkOperations<T extends Record<string, unknown>> {
    /** New rows to insert. IDs are server-assigned and returned in {@link BulkResult.insertedIds}. */
    inserts?: CrudCreateInput<T>[];
    /** Partial updates keyed by id. `patch` is a shallow merge on top of the stored row. */
    updates?: Array<{
        id: string;
        patch: Partial<T>;
    }>;
    /** IDs to delete. */
    deletes?: string[];
}
/**
 * Result of a bulk CRUD operation. Each id list preserves the input order of the
 * corresponding bucket in {@link BulkOperations}.
 *
 * @example
 * const r: BulkResult = await adapter.bulk('events', {
 *   inserts: [{ title: 'A' }],
 *   deletes: ['x'],
 * });
 * r.insertedIds; // ['evt_123']
 * r.deletedIds;  // ['x']
 *
 * @version 0.1.0
 * @since 0.2.0
 * @author AMBROISE PARK Consulting
 */
interface BulkResult {
    /** Server-assigned IDs for `inserts`, in input order. */
    insertedIds: string[];
    /** IDs that were updated, in input order. */
    updatedIds: string[];
    /** IDs that were deleted, in input order. */
    deletedIds: string[];
}
/**
 * One collection's worth of operations inside a {@link bulkAcross} call.
 *
 * Inserts may include a caller-provided `id` for cross-collection pre-minting:
 * mint the ID client-side, use it in both collections, and pass `dependsOn` to
 * ensure write order.
 *
 * @template T - Entity type for this batch's collection.
 *
 * @example
 * const customerId = generateUUID();
 * await bulkAcross([
 *   {
 *     collection: 'customers',
 *     inserts: [{ id: customerId, ...customerData }],
 *     schemas: { create: customerCreateSchema },
 *   },
 *   {
 *     collection: 'inquiries',
 *     inserts: [{ customerId, ...inquiryData }],
 *     schemas: { create: inquiryCreateSchema },
 *     dependsOn: ['customers'],
 *   },
 * ]);
 *
 * @version 0.1.0
 * @since 0.3.0
 * @author AMBROISE PARK Consulting
 */
interface BulkAcrossBatch<T extends Record<string, unknown> = Record<string, unknown>> {
    /** Target collection name. */
    collection: string;
    /** Rows to insert. May include a caller-provided `id` for pre-minting. */
    inserts?: Array<CrudCreateInput<T> & {
        id?: string;
    }>;
    /** Rows to update (partial patches). */
    updates?: Array<{
        id: string;
        patch: Partial<T>;
    }>;
    /** Document IDs to delete. */
    deletes?: string[];
    /** Schemas for insert validation + PII resolution. */
    schemas: {
        create?: dndevSchema<T>;
        draft?: dndevSchema<T>;
        update?: dndevSchema<T>;
    };
    /**
     * Collections that must be written first.
     * Batches with no `dependsOn` run in parallel with other dependency-free batches.
     */
    dependsOn?: string[];
}
/**
 * Result of a {@link bulkAcross} call. Per-collection results keyed by collection name.
 *
 * @version 0.1.0
 * @since 0.3.0
 * @author AMBROISE PARK Consulting
 */
interface BulkAcrossResult {
    /** Per-collection {@link BulkResult}, keyed by collection name. */
    results: Record<string, BulkResult>;
}

/** Single where clause for a query. operator accepts CrudOperator or string so consumer code can use variables or literals ('in', '==', etc.) without importing CRUD_OPERATORS. */
interface QueryWhereClause {
    field: string;
    operator: CrudOperator;
    value: unknown;
}
/** Order-by clause for a query. direction accepts 'asc' | 'desc' or string so consumer code can use variables. */
interface QueryOrderBy {
    field: string;
    direction?: OrderDirection;
}
/**
 * Query options for collection queries.
 * Provider-agnostic — each adapter maps these to its native query API.
 *
 * Default `limit` is **1000** (server max: 1000). For collections > 1000 items,
 * use server-side pagination with `startAfter` cursor.
 *
 * @example
 * // Fetch all (up to 1000)
 * { where: [{ field: 'status', operator: '==', value: 'available' }] }
 *
 * @example
 * // Paginate server-side
 * { limit: 50, startAfter: lastCursorId }
 */
interface QueryOptions {
    where?: QueryWhereClause[];
    orderBy?: QueryOrderBy[];
    /** Max items to fetch. Default: 1000, max: 1000. Use server pagination for larger collections. */
    limit?: number;
    /** Opaque cursor for pagination — value of the first orderBy field from the previous page's lastVisible */
    startAfter?: string | null;
}
/**
 * Paginated query result returned by adapter.query().
 * @template T - The entity type
 */
interface PaginatedQueryResult<T> {
    items: T[];
    total?: number;
    hasMore?: boolean;
    /** Opaque cursor for the next page */
    lastVisible?: string | null;
}
/**
 * Return shape of the CRUD list-query option builder
 * (`CrudService.getListQueryOptions` / `getListQueryOptionsImpl`).
 *
 * This is the TanStack-compatible descriptor handed to `useQuery()`. Lifted
 * into `@donotdev/core` so the CRUD facade and its impl can both annotate
 * their return types against a single source — the inferred-only shape
 * caused circular type inference (TS7023) after the 1949-LOC CrudService
 * split.
 *
 * **Invariant:** `queryKey[3]` is `JSON.stringify(queryOptions)` — list and
 * listCard views share the same key, yielding one network read.
 *
 * @template T - The entity type in list items
 */
interface CrudListQuery<T> {
    readonly queryKey: readonly ['crud', string, 'query', string];
    readonly queryFn: () => Promise<PaginatedQueryResult<T>>;
    readonly staleTime: number;
}
/**
 * Return shape of the CRUD single-document query option builder
 * (`CrudService.getDocQueryOptions` / `getDocQueryOptionsImpl`).
 *
 * TanStack-compatible descriptor for `useQuery()`. See `CrudListQuery` for
 * the rationale behind promoting this shape into core types.
 *
 * @template T - The document entity type
 */
interface CrudDocQuery<T> {
    readonly queryKey: readonly ['crud', string, 'get', string];
    readonly queryFn: () => Promise<T | null>;
    readonly staleTime: number;
}
/** Callback for single-document subscriptions */
type DocumentSubscriptionCallback<T> = (data: T | null, error?: Error) => void;
/** Callback for collection subscriptions */
type CollectionSubscriptionCallback<T> = (data: T[], error?: Error) => void;
/** Options for CRUD operations */
interface CrudOperationOptions {
    /** AbortSignal to cancel the operation */
    signal?: AbortSignal;
}

/**
 * @fileoverview CRUD Adapter Interface
 * @description Provider-agnostic interface for CRUD data access.
 * Any backend (Firestore, Supabase, REST, Postgres) must implement this contract.
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */

/**
 * Provider-agnostic CRUD adapter interface.
 *
 * Implementations:
 * - `FirestoreAdapter` (Firestore direct)
 * - `FunctionsAdapter` (Firebase callable functions)
 * - Future: Supabase, REST, Postgres adapters
 *
 * @template All methods accept `dndevSchema` for validation/transformation.
 * Adapters that don't need schema can ignore it.
 *
 * @version 0.1.0
 * @since 0.5.0
 */
interface ICrudAdapter {
    /**
     * When true, this adapter enforces field-level security server-side.
     * Only server-side adapters may access entities with restricted field visibility.
     * Defaults to false (direct/client-side adapters).
     */
    readonly serverSideOnly?: boolean;
    /**
     * When true, field-level and row-level security is enforced at the database layer
     * (e.g. Supabase RLS + column grants). The framework visibility gate is bypassed
     * because the DB rejects unauthorized reads before any data leaves the server.
     *
     * **Supabase:** requires RLS enabled on every table + column-level grants per role.
     * **Firestore:** Rules are row-level only — field-level filtering needs FunctionsAdapter.
     */
    readonly dbLevelSecurity?: boolean;
    /** Fetch a single document by ID. Returns null if not found. */
    get<T>(collection: string, id: string, schema?: dndevSchema<unknown>, options?: CrudOperationOptions): Promise<T | null>;
    /** Create a new document with auto-generated ID. Returns the ID + parsed data. */
    add<T>(collection: string, data: T, schema?: dndevSchema<T>, options?: CrudOperationOptions): Promise<{
        id: string;
        data: Record<string, unknown>;
    }>;
    /**
     * Execute a bulk transactional operation.
     * - All ops commit atomically. One transaction/writeBatch.
     * - One round-trip where the transport supports it.
     * - Empty ops returns a zeroed BulkResult without wire contact.
     * - Throws on partial failure; never leaves store in mixed state.
     *
     * @example
     * const r = await adapter.bulk('events', { inserts: [{ title: 'A' }], deletes: ['x'] });
     * r.insertedIds; r.deletedIds;
     */
    bulk<T extends Record<string, unknown>>(collection: string, ops: BulkOperations<T>, schema?: dndevSchema<T>, options?: CrudOperationOptions): Promise<BulkResult>;
    /** Set/replace a document by ID (upsert semantics). */
    set<T>(collection: string, id: string, data: T, schema?: dndevSchema<T>, options?: CrudOperationOptions): Promise<void>;
    /** Partial update a document by ID. */
    update<T>(collection: string, id: string, data: Partial<T>, options?: CrudOperationOptions): Promise<void>;
    /** Delete a document by ID. */
    delete(collection: string, id: string, options?: CrudOperationOptions): Promise<void>;
    /** Query a collection with filters, ordering, and pagination. schemaType accepts 'list' | 'listCard' or string. */
    query<T>(collection: string, options: QueryOptions, schema?: dndevSchema<unknown>, schemaType?: ListSchemaType | string, operationOptions?: CrudOperationOptions): Promise<PaginatedQueryResult<T>>;
    /**
     * Subscribe to real-time changes on a single document.
     * Optional — adapters that don't support real-time can throw or return a no-op unsubscribe.
     */
    subscribe?<T>(collection: string, id: string, callback: DocumentSubscriptionCallback<T>, schema?: dndevSchema<unknown>): () => void;
    /**
     * Subscribe to real-time changes on a collection query.
     * Optional — adapters that don't support real-time can throw or return a no-op unsubscribe.
     */
    subscribeToCollection?<T>(collection: string, options: QueryOptions, callback: CollectionSubscriptionCallback<T>, schema?: dndevSchema<unknown>): () => void;
}

/** Supported aggregation operations */
declare const AGGREGATE_OPERATIONS: {
    readonly COUNT: "count";
    readonly SUM: "sum";
    readonly AVG: "avg";
    readonly MIN: "min";
    readonly MAX: "max";
};
/** Aggregation operation type derived from AGGREGATE_OPERATIONS constant. */
type AggregateOperation = (typeof AGGREGATE_OPERATIONS)[keyof typeof AGGREGATE_OPERATIONS];
/** Filter operators for aggregation (subset of CRUD_OPERATORS) */
declare const AGGREGATE_FILTER_OPERATORS: {
    readonly EQ: "==";
    readonly NEQ: "!=";
    readonly LT: "<";
    readonly LTE: "<=";
    readonly GT: ">";
    readonly GTE: ">=";
};
/** Filter operator type for aggregation queries. */
type AggregateFilterOperator = (typeof AGGREGATE_FILTER_OPERATORS)[keyof typeof AGGREGATE_FILTER_OPERATORS];
/**
 * Single metric definition for aggregation
 *
 * @example
 * ```typescript
 * // Count all documents
 * { field: '*', operation: 'count', as: 'total' }
 *
 * // Sum a numeric field
 * { field: 'price', operation: 'sum', as: 'totalValue' }
 *
 * // Count with filter
 * {
 *   field: '*',
 *   operation: 'count',
 *   as: 'availableCount',
 *   filter: { field: 'status', operator: '==', value: 'available' }
 * }
 * ```
 */
interface MetricDefinition {
    /** Field to aggregate ('*' for count all) */
    field: string;
    /** Aggregation operation */
    operation: AggregateOperation;
    /** Output name for this metric */
    as: string;
    /** Optional filter for this metric */
    filter?: {
        field: string;
        operator: AggregateFilterOperator;
        value: any;
    };
}
/**
 * Group by definition for aggregation
 *
 * @example
 * ```typescript
 * {
 *   field: 'status',
 *   metrics: [
 *     { field: '*', operation: 'count', as: 'count' },
 *     { field: 'price', operation: 'sum', as: 'value' },
 *   ]
 * }
 * ```
 */
interface GroupByDefinition {
    /** Field to group by */
    field: string;
    /** Metrics to compute per group */
    metrics: MetricDefinition[];
}
/**
 * Aggregation configuration for entity analytics
 *
 * @example
 * ```typescript
 * const carsAnalyticsConfig: AggregateConfig = {
 *   metrics: [
 *     { field: '*', operation: 'count', as: 'total' },
 *     { field: 'price', operation: 'sum', as: 'totalValue' },
 *     { field: 'price', operation: 'avg', as: 'avgPrice' },
 *   ],
 *   groupBy: [
 *     {
 *       field: 'status',
 *       metrics: [
 *         { field: '*', operation: 'count', as: 'count' },
 *         { field: 'price', operation: 'sum', as: 'value' },
 *       ],
 *     },
 *   ],
 *   where: [['isActive', '==', true]],
 * };
 * ```
 */
interface AggregateConfig {
    /** Top-level metrics (computed on entire collection) */
    metrics?: MetricDefinition[];
    /** Group by configurations */
    groupBy?: GroupByDefinition[];
    /** Optional global filters */
    where?: Array<[string, AggregateFilterOperator | string, unknown]>;
}
/**
 * Request payload for aggregate function calls
 */
interface AggregateRequest {
    /** Optional runtime filters (merged with config filters) */
    where?: Array<[string, AggregateFilterOperator | string, unknown]>;
    /** Optional date range filter */
    dateRange?: {
        field: string;
        start?: string;
        end?: string;
    };
}
/**
 * Response from aggregate function
 */
interface AggregateResponse {
    /** Computed top-level metrics */
    metrics: Record<string, number | null>;
    /** Grouped metrics by field */
    groups: Record<string, Record<string, Record<string, number | null>>>;
    /** Metadata about the aggregation */
    meta: {
        collection: string;
        totalDocs: number;
        computedAt: string;
    };
}

/**
 * @fileoverview CRUD Component Props Types
 * @description Shared prop types for CRUD components used across UI, Templates, and CRUD packages
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Shared base props for entity browsing components (table and card grid).
 * Both fetch the same data — just render differently based on entity field config.
 */
interface EntityBrowseBaseProps {
    /** The entity definition */
    entity: AnyEntity;
    /**
     * Base path for view. Default: `/${collection}`. View = `${basePath}/${id}`.
     */
    basePath?: string;
    /**
     * Called when user clicks a row/card. If provided, overrides default navigation to basePath/:id (e.g. open sheet).
     */
    onClick?: (id: string) => void;
    /** Hide filters section (default: false) */
    hideFilters?: boolean;
    /** Current user role (for UI toggle only - backend enforces security) */
    userRole?: string;
    /** Optional query constraints (server-side filtering via adapter) */
    queryOptions?: QueryOptions;
    /** Cache stale time in ms */
    staleTime?: number;
    /**
     * Tone for the filter and results Section wrappers.
     * Use 'base' or 'muted' when the app has an image background so sections are readable.
     * @default 'ghost' (transparent — inherits parent background)
     */
    tone?: 'ghost' | 'base' | 'muted' | 'contrast' | 'accent';
    /**
     * Static data for design-time preview.
     * When provided, the component renders this data directly instead of
     * fetching from the CRUD backend. All interactive elements (edit, delete,
     * create, filters, favorites, navigation) are rendered but disabled.
     *
     * No CrudProvider or backend connection required.
     * Hooks are never called - rendering delegates to a standalone preview component.
     *
     * @example
     * ```tsx
     * // Design preview with mock data
     * <EntityCardList entity={productEntity} preview={mockProducts} />
     *
     * // Spec chat: entity generated from user description
     * <EntityList entity={specEntity} preview={generateMockData(specEntity, 6)} />
     * ```
     */
    preview?: (Record<string, unknown> & {
        id: string;
    })[];
}
/** Props for the entity data table component with server/client pagination. */
interface EntityListProps extends EntityBrowseBaseProps {
    /**
     * Pagination mode:
     * - `'auto'` (default) — fetches up to 1000 client-side. Auto-switches to server if total > 1000.
     * - `'client'` — forces client-side (all data in memory, instant search/sort/filter).
     * - `'server'` — forces server-side (cursor pagination, one page at a time).
     */
    pagination?: 'auto' | 'client' | 'server';
    /** Page size - passed to DataTable. If not provided, DataTable uses its default (12) */
    pageSize?: number;
    /**
     * Enable export to CSV functionality
     * @default true (admin tables typically need export)
     */
    exportable?: boolean;
}
/** Props for the entity card grid component with filtering and sorting. */
interface EntityCardListProps extends EntityBrowseBaseProps {
    /** Grid columns (responsive) - defaults to [1, 2, 3, 4] */
    cols?: number | [number, number, number, number];
    /** Optional filter function to filter items client-side */
    filter?: (item: Record<string, unknown> & {
        id: string;
    }) => boolean;
    /**
     * Custom label for the results section title.
     * Receives the current item count so you can handle pluralization and empty state.
     * When not provided, defaults to the built-in i18n label ("Found N occurrences").
     *
     * @param count - Number of items after all filters are applied
     * @returns The string to display as the results section title
     *
     * @example
     * ```tsx
     * // Simple override
     * <EntityCardList
     *   entity={apartmentEntity}
     *   resultLabel={(count) =>
     *     count === 0
     *       ? 'No apartments available'
     *       : count === 1
     *         ? 'Your future home is right here'
     *         : `Your future home is among these ${count} apartments`
     *   }
     * />
     * ```
     */
    resultLabel?: (count: number) => string;
    /** Render a custom overlay on each card (e.g. status stamp). Receives the item. */
    renderCardOverlay?: (item: EntityRecord & {
        id: string;
    }) => ReactNode;
    /** Client-side sort: field config, comparator function, or null to disable. Defaults to entity.defaultSort. */
    clientSort?: {
        field: string;
        direction?: 'asc' | 'desc';
    } | ((a: any, b: any) => number) | null;
    /** Make filter/results sections collapsible. @default false */
    collapsible?: boolean;
    /** Initial open state when collapsible. Only relevant when `collapsible` is true. */
    defaultOpen?: boolean;
}
/**
 * Props for CrudCard — presentational card built from entity + item + field slots.
 * Not route-aware: parent (e.g. EntityCardList) provides detailHref or onClick.
 * For a11y/SEO prefer detailHref so the card is wrapped in a Link.
 */
interface CrudCardProps {
    /** The list item (must have id) */
    item: EntityRecord & {
        id: string;
    };
    /** The entity definition (for entity.fields and formatting) */
    entity: AnyEntity;
    /**
     * Called when card is clicked (e.g. open sheet instead of navigating).
     * Navigation via Link is handled by the parent wrapper (CrudCardLink), not by CrudCard itself.
     */
    onClick?: (id: string) => void;
    /** Field names for card title (values joined with space) */
    titleFields?: string[];
    /** Field names for subtitle */
    subtitleFields?: string[];
    /** Field names for content body (label + value rows) */
    contentFields?: string[];
    /** Field names for footer */
    footerFields?: string[];
    /** When true, show delete button with confirm dialog */
    showDelete?: boolean;
    /** Optional actions slot (e.g. favorites heart) rendered in card corner */
    renderActions?: ReactNode;
    /** Optional overlay rendered over the full image area (position absolute, centered, pointer-events none) */
    renderOverlay?: ReactNode;
    /** Optional className for the card wrapper */
    className?: string;
}
/** Props for the entity form renderer with create/edit modes, validation, and navigation. */
interface EntityFormRendererProps<T extends EntityRecord = EntityRecord> {
    /** Entity definition - pass the full entity from defineEntity() */
    entity: AnyEntity;
    /** Form submission handler */
    onSubmit: (data: T) => void | Promise<void>;
    /** Translation function */
    t?: (key: string, options?: Record<string, unknown>) => string;
    /** Additional CSS classes */
    className?: string;
    /** Submit button text */
    submitText?: string;
    /**
     * Whether form data is loading (shows loading overlay)
     * Use this when fetching existing entity data for edit mode
     */
    loading?: boolean;
    /** Initial form values */
    defaultValues?: Partial<T>;
    /** Submit button variant */
    submitVariant?: 'primary' | 'destructive' | 'outline' | 'ghost' | 'link';
    /** Secondary button text */
    secondaryButtonText?: string;
    /** Secondary button variant */
    secondaryButtonVariant?: 'primary' | 'destructive' | 'outline' | 'ghost' | 'link';
    /** Secondary button submission handler */
    onSecondarySubmit?: (data: T) => void | Promise<void>;
    /**
     * Current viewer's role for editability checks.
     * Auto-detected from auth when not provided. Pass explicitly to override (e.g. View-As preview).
     * Fallback chain: prop → useAuthSafe('userRole') → 'guest'
     */
    viewerRole?: string;
    /**
     * Form operation type
     * @default 'create' (or 'edit' if defaultValues provided)
     */
    operation?: 'create' | 'edit';
    /**
     * Optional form ID for tracking loading state.
     * If not provided, one will be generated automatically.
     */
    formId?: string;
    /**
     * Cancel button text. If provided, shows a cancel button.
     * If not provided but onCancel is provided, shows default "Cancel" text.
     * Set to null to explicitly hide cancel button.
     */
    cancelText?: string | null;
    /**
     * Success path - full path to navigate after successful submit (e.g., `/products`).
     * If not provided, stays on page (edit) or relies on onSubmit to navigate (create).
     */
    successPath?: string;
    /**
     * Cancel path - full path (e.g., `/products`). If not provided, navigates back.
     * If onCancel callback is provided, it takes precedence over cancelPath.
     */
    cancelPath?: string;
    /**
     * Callback when cancel is clicked (after confirmation if dirty).
     * If not provided, cancel navigates to cancelPath or `/${collection}`.
     * If provided, cancel button will show (with cancelText or default "Cancel").
     */
    onCancel?: () => void;
    /**
     * Hide visibility indicators (badges + View As toggle).
     * When false (default), shows badge next to non-guest fields and View As role selector.
     * @default false
     */
    hideVisibilityInfo?: boolean;
    /**
     * Explicit form instance key for isolation between records.
     * When provided, React remounts the form whenever this value changes —
     * ensuring clean state when navigating between entities (e.g. `/cars/:id`).
     *
     * Pass the route ID: `instanceKey={id}`
     *
     * @example
     * ```tsx
     * // Automatically isolates form state per car — no manual reset needed
     * <EntityFormRenderer entity={carEntity} instanceKey={id} defaultValues={carData} />
     * ```
     */
    instanceKey?: string;
}
/** Props for the entity recommendations section (e.g. "Similar items"). */
interface EntityRecommendationsProps {
    /** The entity definition */
    entity: AnyEntity;
    /** Query constraints — caller defines "related by what" (where, limit, etc.) */
    queryOptions: QueryOptions;
    /** Section title (e.g. "Similar apartments") */
    title?: string;
    /** Base path for card links. Default: `/${entity.collection}` */
    basePath?: string;
    /** Grid columns — default `[1,1,3,3]` */
    cols?: number | [number, number, number, number];
    /**
     * Tone for the Section wrapper.
     * Use 'base' or 'muted' when the app has an image background so the section is readable.
     * @default 'ghost' (transparent — inherits parent background)
     */
    tone?: 'ghost' | 'base' | 'muted' | 'contrast' | 'accent';
    /** Additional className on wrapper Section */
    className?: string;
}
/** Props for the read-only entity detail renderer with role-based visibility. */
interface EntityDisplayRendererProps<T extends EntityRecord = EntityRecord> {
    /** Entity definition - pass the full entity from defineEntity() */
    entity: AnyEntity;
    /** Entity ID to fetch. Not required when `preview` is provided. */
    id?: string;
    /** Translation function (optional - auto-generated if not provided) */
    t?: (key: string, options?: Record<string, unknown>) => string;
    /** Additional CSS classes */
    className?: string;
    /** Custom loading message */
    loadingMessage?: string;
    /** Custom not found message */
    notFoundMessage?: string;
    /**
     * Current viewer's role for visibility checks.
     * Auto-detected from auth when not provided. Pass explicitly to override.
     * Fallback chain: prop → useAuthSafe('userRole') → 'guest'
     */
    viewerRole?: string;
    /**
     * Field names to exclude from rendering.
     * Use when the page already displays certain fields in a custom hero/header section.
     */
    excludeFields?: string[];
    /**
     * Static data for design-time preview.
     * When provided, renders this record directly instead of fetching by id.
     * The `id` prop becomes unnecessary (ignored when preview is set).
     *
     * @example
     * ```tsx
     * <EntityDisplayRenderer entity={productEntity} preview={mockProduct} />
     * ```
     */
    preview?: Partial<T>;
}

/**
 * @fileoverview CRUD Error Classes
 * @description Error classes raised by the CRUD service and adapters.
 * Each error is a plain {@link Error} subclass so consumers can `instanceof` them.
 *
 * @version 0.1.0
 * @since 0.2.0
 * @author AMBROISE PARK Consulting
 */
/**
 * Thrown when a {@link BulkOperations} payload contains the same id in two
 * mutually-exclusive buckets. The service rejects these up-front, before any
 * write is attempted, so partial state is impossible.
 *
 * @example
 * try {
 *   await crud.bulk({
 *     updates: [{ id: 'a', patch: {} }],
 *     deletes: ['a'],
 *   });
 * } catch (err) {
 *   if (err instanceof BulkCollisionError) {
 *     // err.collidingIds === ['a']
 *     // err.where === 'updates-deletes'
 *   }
 * }
 *
 * @version 0.1.0
 * @since 0.2.0
 */
declare class BulkCollisionError extends Error {
    /** IDs that appear in both buckets. Preserves the order they were detected. */
    readonly collidingIds: string[];
    /** Which two buckets collided. */
    readonly where: 'updates-deletes' | 'inserts-updates';
    /**
     * @param collidingIds - IDs present in both buckets.
     * @param where - The pair of buckets that produced the collision.
     */
    constructor(collidingIds: string[], where: 'updates-deletes' | 'inserts-updates');
}
/**
 * Thrown by {@link bulkAcross} before any side effect when `dependsOn`
 * relationships form a cycle. The `cycle` array lists the collection names
 * that form the circular dependency chain.
 *
 * @example
 * try {
 *   await crud.bulkAcross([
 *     { collection: 'a', dependsOn: ['b'], ... },
 *     { collection: 'b', dependsOn: ['a'], ... },
 *   ]);
 * } catch (err) {
 *   if (err instanceof BulkAcrossCycleError) {
 *     console.error(err.cycle); // ['a', 'b']
 *   }
 * }
 *
 * @version 0.1.0
 * @since 0.3.0
 */
declare class BulkAcrossCycleError extends Error {
    /** Collection names that form the cycle. */
    readonly cycle: string[];
    constructor(cycle: string[]);
}
/**
 * Thrown by an adapter whose `bulk()` method has not yet been implemented.
 * Lets the interface stay required across all providers while individual
 * adapters can land their implementation incrementally.
 *
 * @example
 * // Inside an adapter stub:
 * async bulk() {
 *   throw new BulkNotImplementedError('restcrud');
 * }
 *
 * @version 0.1.0
 * @since 0.2.0
 */
declare class BulkNotImplementedError extends Error {
    /** Adapter identifier (e.g. `'firebase-firestore'`, `'supabase'`). */
    readonly adapterName: string;
    /**
     * @param adapterName - Name of the adapter that has not implemented `bulk()`.
     */
    constructor(adapterName: string);
}

/**
 * @fileoverview Email Constants
 * @description Provider IDs, error codes, and defaults for email feature.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */
/** Supported email providers */
declare const EMAIL_PROVIDERS: {
    readonly RESEND: "resend";
};
/** Email error codes */
declare const EMAIL_ERROR_CODES: {
    readonly UNKNOWN: "unknown";
    readonly UNAUTHENTICATED: "unauthenticated";
    readonly INVALID_REQUEST: "invalid_request";
    readonly PROVIDER_ERROR: "provider_error";
    readonly TEMPLATE_NOT_FOUND: "template_not_found";
    readonly RATE_LIMIT_EXCEEDED: "rate_limit_exceeded";
    readonly MISSING_API_KEY: "missing_api_key";
};

/**
 * @fileoverview Email Schemas
 * @description Valibot schemas for email request/response validation.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */

/** Schema for send email request (caller → handler) */
declare const SendEmailRequestSchema: v.ObjectSchema<{
    /** Template ID from the registry */
    readonly templateId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    /** Recipient email address */
    readonly to: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
    /** Template data (shape depends on template) */
    readonly data: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    /** Locale for i18n rendering (default: 'fr') */
    readonly locale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 2, undefined>, v.MaxLengthAction<string, 5, undefined>]>, "fr">;
    /** Override "from" address */
    readonly from: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Override reply-to address */
    readonly replyTo: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/** Schema for send email response */
declare const SendEmailResponseSchema: v.ObjectSchema<{
    /** Whether the email was sent successfully */
    readonly success: v.BooleanSchema<undefined>;
    /** Provider message ID (for tracking) */
    readonly messageId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Error message if sending failed */
    readonly error: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/** Request payload for sending an email. */
type SendEmailRequest = v.InferOutput<typeof SendEmailRequestSchema>;
/** Response payload after sending an email. */
type SendEmailResponse = v.InferOutput<typeof SendEmailResponseSchema>;
declare function validateSendEmailRequest(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    /** Template ID from the registry */
    readonly templateId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    /** Recipient email address */
    readonly to: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.EmailAction<string, undefined>]>;
    /** Template data (shape depends on template) */
    readonly data: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    /** Locale for i18n rendering (default: 'fr') */
    readonly locale: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 2, undefined>, v.MaxLengthAction<string, 5, undefined>]>, "fr">;
    /** Override "from" address */
    readonly from: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Override reply-to address */
    readonly replyTo: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>>;
declare function validateSendEmailResponse(data: unknown): v.SafeParseResult<v.ObjectSchema<{
    /** Whether the email was sent successfully */
    readonly success: v.BooleanSchema<undefined>;
    /** Provider message ID (for tracking) */
    readonly messageId: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    /** Error message if sending failed */
    readonly error: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
}, undefined>>;

/**
 * @fileoverview Email Types
 * @description Type definitions for email feature. Provider abstraction, template registry, route config.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */

/** Email provider type */
type EmailProvider = (typeof EMAIL_PROVIDERS)[keyof typeof EMAIL_PROVIDERS];
/** Email error code type */
type EmailErrorCode = (typeof EMAIL_ERROR_CODES)[keyof typeof EMAIL_ERROR_CODES];
/**
 * Email template with i18n support.
 * Templates render subject + HTML body from typed data and locale.
 *
 * @template TData - Shape of the template data
 */
interface EmailTemplate<TData extends Record<string, unknown> = Record<string, unknown>> {
    /** Render email subject for a given locale */
    subject: (data: TData, locale: string) => string;
    /** Render email HTML body for a given locale */
    html: (data: TData, locale: string) => string;
}
/**
 * Registry of named email templates.
 * Each key is a template ID used in send requests.
 */
type EmailTemplateRegistry = Record<string, EmailTemplate<any>>;
/** Configuration for email feature (consumer-facing) */
interface EmailConfig {
    /** Email provider */
    provider: EmailProvider;
    /** Default "from" address */
    defaultFrom: string;
    /** Default reply-to address */
    replyTo?: string;
}
/** Email route configuration (server-side) */
interface EmailRouteConfig {
    /** Email provider */
    provider: EmailProvider;
    /** Default "from" address (e.g., "Frabled <noreply@frabled.com>") */
    defaultFrom: string;
    /** Default reply-to address */
    replyTo?: string;
    /** Registered templates */
    templates: EmailTemplateRegistry;
}

/**
 * @fileoverview Error Types Used Throughout the DoNotDev Platform
 * @description Centralized definition of error types to ensure consistency across packages. Defines standard error codes, error classes, and error handling types.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Error types used throughout the DoNotDev platform
 * Single source of truth: const objects + derived types.
 */
/**
 * Standard error codes used within the DoNotDev platform.
 * Mapped to HTTP status codes or used for specific error handling logic.
 */
declare const ERROR_CODES: {
    readonly ALREADY_EXISTS: "already-exists";
    readonly CANCELLED: "cancelled";
    readonly DEADLINE_EXCEEDED: "deadline-exceeded";
    readonly DELETE_ACCOUNT_REQUIRES_SERVER: "DELETE_ACCOUNT_REQUIRES_SERVER";
    readonly INTERNAL: "internal";
    readonly INVALID_ARGUMENT: "invalid-argument";
    readonly NOT_FOUND: "not-found";
    readonly PERMISSION_DENIED: "permission-denied";
    readonly RATE_LIMIT_EXCEEDED: "rate-limit-exceeded";
    readonly TIMEOUT: "timeout";
    readonly UNAUTHENTICATED: "unauthenticated";
    readonly UNAVAILABLE: "unavailable";
    readonly UNIMPLEMENTED: "unimplemented";
    readonly UNKNOWN: "unknown";
    readonly VALIDATION_FAILED: "validation-failed";
};
/** Standardized error code derived from ERROR_CODES constant. */
type ErrorCode = (typeof ERROR_CODES)[keyof typeof ERROR_CODES];
/**
 * Severity levels for error notifications and logging
 */
declare const ERROR_SEVERITY: {
    readonly ERROR: "error";
    readonly WARNING: "warning";
    readonly INFO: "info";
    readonly SUCCESS: "success";
};
/** Error severity level for notifications and logging. */
type ErrorSeverity = (typeof ERROR_SEVERITY)[keyof typeof ERROR_SEVERITY];
/**
 * Error types used in entity hooks
 */
declare const ENTITY_HOOK_ERRORS: {
    readonly INTERNAL_ERROR: "INTERNAL_ERROR";
    readonly VALIDATION_ERROR: "VALIDATION_ERROR";
    readonly PERMISSION_DENIED: "PERMISSION_DENIED";
    readonly NOT_FOUND: "NOT_FOUND";
    readonly ALREADY_EXISTS: "ALREADY_EXISTS";
    readonly NETWORK_ERROR: "NETWORK_ERROR";
};
/** Error type for entity hook operations (CRUD mutations). */
type EntityHookErrors = (typeof ENTITY_HOOK_ERRORS)[keyof typeof ENTITY_HOOK_ERRORS];
/**
 * Maps Firebase error codes to entity hook error types
 * Used for consistent error handling across the platform
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const FIREBASE_ERROR_MAP: Record<string, {
    type: EntityHookErrors;
    message: string;
}>;
/**
 * Error class for standardized entity hook errors
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare class EntityHookError extends Error {
    type: EntityHookErrors;
    originalError?: unknown;
    constructor(type: EntityHookErrors, message: string, originalError?: unknown);
}
/**
 * Error source types for tracking where errors originate
 */
declare const ERROR_SOURCE: {
    readonly AUTH: "auth";
    readonly OAUTH: "oauth";
    readonly FIREBASE: "firebase";
    readonly API: "api";
    readonly VALIDATION: "validation";
    readonly ENTITY: "entity";
    readonly UI: "ui";
    readonly UNKNOWN: "unknown";
};
/** Origin of an error for tracking and reporting. */
type ErrorSource = (typeof ERROR_SOURCE)[keyof typeof ERROR_SOURCE];
/**
 * Standardized error class for the DoNotDev platform
 * Single source of truth with optional fields for all use cases
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare class DoNotDevError extends Error {
    /** The error code categorizing this error */
    readonly code: ErrorCode;
    /** Optional additional details or context about the error */
    readonly details?: Record<string, any>;
    /** The source system where the error originated */
    readonly source?: ErrorSource;
    /** Original error if this is wrapping another error */
    readonly originalError?: Error;
    /** Additional context for the error */
    readonly context?: Record<string, any>;
    /** Whether this error should be displayed to the user */
    readonly displayable?: boolean;
    /** Flag to track if a user message has been provided */
    readonly userMessageProvided?: boolean;
    constructor(message: string, code?: ErrorCode, options?: {
        details?: Record<string, any>;
        source?: ErrorSource;
        originalError?: Error;
        context?: Record<string, any>;
        displayable?: boolean;
        userMessageProvided?: boolean;
    });
    toString(): string;
    toJSON(): object;
}

/**
 * @fileoverview Security Types
 * @description Core security interface definitions. Implemented by @donotdev/security.
 * Keeping these in @donotdev/core avoids circular deps between packages.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Audit event types (SOC2 CC6, CC7, C1, P1-P8).
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuditEventType = 'auth.login.success' | 'auth.login.failure' | 'auth.logout' | 'auth.locked' | 'auth.unlocked' | 'auth.mfa.enrolled' | 'auth.mfa.challenged' | 'auth.session.expired' | 'auth.password.reset' | 'auth.signup.consent' | 'auth.role.changed' | 'crud.create' | 'crud.read' | 'crud.update' | 'crud.delete' | 'crud.bulk' | 'pii.access' | 'pii.export' | 'pii.erase' | 'rate_limit.exceeded' | 'anomaly.detected' | 'config.changed';
/**
 * A single structured audit log entry.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuditEvent {
    type: AuditEventType;
    timestamp: string;
    userId?: string;
    collection?: string;
    docId?: string;
    ip?: string;
    userAgent?: string;
    metadata?: Record<string, string | number | boolean>;
}
/**
 * Persistence-backed rate limit config (server-side: maxAttempts / windowMs / blockDurationMs).
 * Used by RateLimitBackend implementations (Firestore, Postgres, Redis).
 * Distinct from the client-side RateLimitConfig in @donotdev/types/utils.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ServerRateLimitConfig {
    /** Max requests allowed within the window. */
    maxAttempts: number;
    /** Window duration in milliseconds. */
    windowMs: number;
    /** Block duration in milliseconds after limit is exceeded. */
    blockDurationMs: number;
}
/**
 * Result from a server-side rate limit check.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ServerRateLimitResult {
    allowed: boolean;
    remaining: number;
    resetAt: Date | null;
    blockRemainingSeconds: number | null;
}
/**
 * Pluggable rate limit backend for DndevSecurity.
 * Implement to swap the default in-memory limiter with Firestore, Postgres, Redis, etc.
 *
 * @example
 * ```typescript
 * import { checkRateLimitWithFirestore } from '@donotdev/functions/shared';
 * const security = new DndevSecurity({
 *   rateLimitBackend: { check: (key, cfg) => checkRateLimitWithFirestore(key, cfg) },
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RateLimitBackend {
    check(key: string, config: ServerRateLimitConfig): Promise<ServerRateLimitResult>;
}
/**
 * Minimal auth hardening interface exposed by SecurityContext.
 * Auth adapters delegate lockout to this when security is injected,
 * ensuring a single lockout source of truth that respects user config.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthHardeningContext {
    /** @throws if identifier is currently locked out */
    checkLockout(identifier: string): void;
    /** Record a failed auth attempt; may trigger lockout */
    recordFailure(identifier: string): void;
    /** Clear failure counter on successful auth */
    recordSuccess(identifier: string): void;
}
/**
 * Security context interface consumed by CrudService and auth adapters.
 * Implemented by DndevSecurity in @donotdev/security/server.
 *
 * Pass an instance via CrudService.setSecurity() or auth adapter constructors.
 * When not provided, no audit logging, rate limiting, or encryption is applied.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SecurityContext {
    /** Emit a structured audit event */
    audit(event: Omit<AuditEvent, 'timestamp'>): void | Promise<void>;
    /**
     * Check rate limit for a key + operation.
     * @throws {Error} when threshold is exceeded
     */
    checkRateLimit(key: string, operation: 'read' | 'write'): Promise<void>;
    /** Encrypt named PII fields in a data object (returns new object) */
    encryptPii<T extends Record<string, unknown>>(data: T, piiFields: string[]): T;
    /** Decrypt named PII fields in a data object (returns new object) */
    decryptPii<T extends Record<string, unknown>>(data: T, piiFields: string[]): T;
    /**
     * Auth hardening — when present, auth adapters delegate brute-force lockout here
     * instead of using their own hardcoded Maps, ensuring injected config is respected.
     */
    authHardening?: AuthHardeningContext;
    /**
     * Record a behavioral anomaly event (e.g. bulk deletes, bulk reads, auth failures).
     * Optional — no-op when not implemented. CrudService calls this after write mutations
     * so the anomaly detector can fire alerts when thresholds are breached.
     *
     * @param type - Anomaly type string (must match AnomalyType in @donotdev/security)
     * @param userId - User who triggered the anomaly (undefined = system / anonymous)
     */
    recordAnomaly?(type: string, userId?: string): void;
}

/**
 * @fileoverview Auth Events
 * @description Event constants and types for auth EDA system. Defines authentication-related event names and types for event-driven architecture.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Authentication event constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const AUTH_EVENTS: {
    readonly AUTH_STATE_CHANGED: "auth.state.changed";
    readonly USER_SIGNED_IN: "auth.user.signed_in";
    readonly USER_SIGNED_OUT: "auth.user.signed_out";
    readonly USER_UPDATED: "auth.user.updated";
    readonly TOKEN_REFRESHED: "auth.token.refreshed";
    readonly SUBSCRIPTION_UPDATED: "auth.subscription.updated";
    readonly SUBSCRIPTION_CHANGED: "auth.subscription.changed";
    readonly SUBSCRIPTION_CANCELLED: "auth.subscription.cancelled";
    readonly SUBSCRIPTION_EXPIRED: "auth.subscription.expired";
    readonly PERMISSIONS_UPDATED: "auth.permissions.updated";
    readonly ACCOUNT_LINKED: "auth.account.linked";
    readonly ACCOUNT_UNLINKED: "auth.account.unlinked";
    readonly ACCOUNT_LINKING_REQUIRED: "auth.account.linking_required";
    readonly AUTH_SUCCESS: "auth.success";
    readonly EMAIL_VERIFICATION_SENT: "auth.email.verification_sent";
    readonly PASSWORD_RESET_SENT: "auth.password.reset_sent";
    readonly AUTH_ERROR: "auth.error";
};
/**
 * Type for authentication event keys
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthEventKey = keyof typeof AUTH_EVENTS;
/**
 * Type for authentication event names
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthEventName = (typeof AUTH_EVENTS)[AuthEventKey];
/**
 * Authentication event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthEventData {
    userId?: string;
    authUser?: any;
    userProfile?: any;
    subscription?: any;
    token?: string;
    permissions?: string[];
    partnerId?: string;
    error?: string;
    errorCode?: string;
    isLoading?: boolean;
    timestamp: Date;
    metadata?: Record<string, any>;
}

/**
 * @fileoverview Billing Events
 * @description Event constants and types for billing EDA system. Defines billing-related event names and types for event-driven architecture.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Billing event constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const BILLING_EVENTS: {
    readonly BILLING_INITIALIZED: "billing.initialized";
    readonly BILLING_ERROR: "billing.error";
    readonly CHECKOUT_SESSION_CREATED: "billing.checkout_session.created";
    readonly CHECKOUT_SESSION_FAILED: "billing.checkout_session.failed";
    readonly SUBSCRIPTION_CREATED: "billing.subscription.created";
    readonly SUBSCRIPTION_UPDATED: "billing.subscription.updated";
    readonly SUBSCRIPTION_CANCELLED: "billing.subscription.cancelled";
    readonly SUBSCRIPTION_RENEWED: "billing.subscription.renewed";
    readonly SUBSCRIPTION_EXPIRED: "billing.subscription.expired";
    readonly SUBSCRIPTION_TRIAL_ENDED: "billing.subscription.trial_ended";
    readonly PAYMENT_SUCCEEDED: "billing.payment.succeeded";
    readonly PAYMENT_FAILED: "billing.payment.failed";
    readonly PAYMENT_REFUNDED: "billing.payment.refunded";
    readonly PAYMENT_METHOD_ADDED: "billing.payment_method.added";
    readonly PAYMENT_METHOD_UPDATED: "billing.payment_method.updated";
    readonly PAYMENT_METHOD_REMOVED: "billing.payment_method.removed";
    readonly PAYMENT_METHOD_DEFAULT_CHANGED: "billing.payment_method.default_changed";
    readonly INVOICE_CREATED: "billing.invoice.created";
    readonly INVOICE_UPDATED: "billing.invoice.updated";
    readonly INVOICE_PAID: "billing.invoice.paid";
    readonly INVOICE_FAILED: "billing.invoice.failed";
    readonly WEBHOOK_RECEIVED: "billing.webhook.received";
    readonly WEBHOOK_PROCESSED: "billing.webhook.processed";
    readonly WEBHOOK_ERROR: "billing.webhook.error";
};
/**
 * Type for billing event keys
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type BillingEventKey = keyof typeof BILLING_EVENTS;
/**
 * Type for billing event names
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type BillingEventName = (typeof BILLING_EVENTS)[BillingEventKey];
/**
 * Billing event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BillingEventData {
    provider?: string;
    config?: Record<string, unknown>;
    invoice?: Record<string, unknown>;
    paymentMethod?: Record<string, unknown>;
    timestamp: Date;
    metadata?: Record<string, unknown>;
}
/**
 * Subscription event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface SubscriptionEventData {
    subscription: Record<string, unknown>;
    previousSubscription?: Record<string, unknown>;
    reason?: string;
    timestamp: Date;
    metadata?: Record<string, unknown>;
}
/**
 * Payment event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PaymentEventData {
    paymentId: string;
    amount: number;
    currency: string;
    status: 'succeeded' | 'failed' | 'pending' | 'refunded';
    subscription?: Record<string, unknown>;
    invoice?: Record<string, unknown>;
    timestamp: Date;
    metadata?: Record<string, unknown>;
}
/**
 * Webhook event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface WebhookEventData {
    provider: string;
    eventType: string;
    data: Record<string, unknown>;
    signature?: string;
    timestamp: Date;
}

/**
 * @fileoverview OAuth Events
 * @description Event constants and types for OAuth EDA system. Defines OAuth-related event names and types for event-driven architecture.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * OAuth event constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const OAUTH_EVENTS: {
    readonly OAUTH_STARTED: "oauth.started";
    readonly OAUTH_SUCCESS: "oauth.success";
    readonly OAUTH_ERROR: "oauth.error";
    readonly OAUTH_CANCELLED: "oauth.cancelled";
    readonly OAUTH_TOKEN_EXCHANGED: "oauth.token.exchanged";
    readonly OAUTH_TOKEN_REFRESHED: "oauth.token.refreshed";
    readonly OAUTH_PARTNER_LINKED: "oauth.partner.linked";
    readonly OAUTH_PARTNER_UNLINKED: "oauth.partner.unlinked";
};
/**
 * Type for OAuth event keys
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthEventKey = keyof typeof OAUTH_EVENTS;
/**
 * Type for OAuth event names
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthEventName = (typeof OAUTH_EVENTS)[OAuthEventKey];
/**
 * OAuth event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthEventData {
    userId?: string;
    partnerId?: string;
    token?: string;
    error?: any;
    timestamp: Date;
    metadata?: Record<string, any>;
}

/**
 * @fileoverview Payload CMS Events
 * @description Event constants and types for Payload CMS webhook events. Defines Payload CMS-related event names and types for event-driven architecture.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Payload CMS event constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const PAYLOAD_EVENTS: {
    readonly DOCUMENT_CREATED: "payload.document.created";
    readonly DOCUMENT_UPDATED: "payload.document.updated";
    readonly DOCUMENT_DELETED: "payload.document.deleted";
    readonly MEDIA_CREATED: "payload.media.created";
    readonly MEDIA_UPDATED: "payload.media.updated";
    readonly MEDIA_DELETED: "payload.media.deleted";
    readonly GLOBAL_UPDATED: "payload.global.updated";
    readonly USER_CREATED: "payload.user.created";
    readonly USER_UPDATED: "payload.user.updated";
    readonly USER_DELETED: "payload.user.deleted";
    readonly CACHE_INVALIDATED: "payload.cache.invalidated";
    readonly PAGE_REGENERATED: "payload.page.regenerated";
};
/**
 * Type for Payload event keys
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PayloadEventKey = keyof typeof PAYLOAD_EVENTS;
/**
 * Type for Payload event names
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type PayloadEventName = (typeof PAYLOAD_EVENTS)[PayloadEventKey];
/**
 * Payload document event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadDocumentEventData {
    collection: string;
    documentId: string;
    operation: string;
    doc: any;
    previousDoc?: any;
    req: any;
    timestamp: string;
}
/**
 * Payload media event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadMediaEventData {
    mediaId: string;
    operation: string;
    media: any;
    previousMedia?: any;
    req: any;
    timestamp: string;
}
/**
 * Payload global event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadGlobalEventData {
    globalSlug: string;
    doc: any;
    previousDoc?: any;
    req: any;
    affectedPages: string[];
    timestamp: string;
}
/**
 * Payload user event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadUserEventData {
    userId: string;
    operation: string;
    user: any;
    req: any;
    timestamp: string;
}
/**
 * Payload cache event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadCacheEventData {
    reason: string;
    scope: string;
    tags: string[];
    priority: string;
    timestamp: string;
}
/**
 * Payload page regeneration event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadPageRegenerationEventData {
    paths: string[];
    reason: string;
    priority: string;
    seoImpact: boolean;
    timestamp: string;
}
/**
 * Payload document interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadDocument {
    id: string;
    [key: string]: any;
}
/**
 * Payload request interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface PayloadRequest {
    method: string;
    url: string;
    headers: Record<string, string>;
    body?: any;
    user?: any;
    timestamp: string;
}

/**
 * @fileoverview Stripe Events
 * @description Event constants and types for Stripe webhook events. Defines Stripe-related event names and types for event-driven architecture.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Stripe event constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const STRIPE_EVENTS: {
    readonly PAYMENT_INTENT_SUCCEEDED: "stripe.payment_intent.succeeded";
    readonly PAYMENT_INTENT_FAILED: "stripe.payment_intent.payment_failed";
    readonly CHECKOUT_SESSION_COMPLETED: "stripe.checkout.session.completed";
    readonly CUSTOMER_CREATED: "stripe.customer.created";
    readonly CUSTOMER_UPDATED: "stripe.customer.updated";
    readonly CUSTOMER_DELETED: "stripe.customer.deleted";
    readonly INVOICE_CREATED: "stripe.invoice.created";
    readonly INVOICE_PAID: "stripe.invoice.paid";
    readonly INVOICE_PAYMENT_FAILED: "stripe.invoice.payment_failed";
    readonly SUBSCRIPTION_CREATED: "stripe.subscription.created";
    readonly SUBSCRIPTION_UPDATED: "stripe.subscription.updated";
    readonly SUBSCRIPTION_DELETED: "stripe.subscription.deleted";
};
/**
 * Type for Stripe event keys
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type StripeEventKey = keyof typeof STRIPE_EVENTS;
/**
 * Type for Stripe event names
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type StripeEventName = (typeof STRIPE_EVENTS)[StripeEventKey];
/**
 * Stripe payment intent event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripePaymentIntentEventData {
    paymentIntentId: string;
    customerId?: string;
    amount: number;
    currency: string;
    status: string;
    metadata?: Record<string, string>;
    timestamp: string;
}
/**
 * Stripe checkout session event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeCheckoutSessionEventData {
    sessionId: string;
    customerId?: string;
    paymentIntentId?: string;
    amount?: number;
    currency?: string;
    customerEmail?: string;
    metadata?: Record<string, string>;
    timestamp: string;
}
/**
 * Stripe customer event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeCustomerEventData {
    customerId: string;
    email?: string;
    name?: string;
    metadata?: Record<string, string>;
    timestamp: string;
}
/**
 * Stripe invoice event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeInvoiceEventData {
    invoiceId: string;
    customerId: string;
    amount: number;
    currency: string;
    status: string;
    hostedInvoiceUrl?: string;
    metadata?: Record<string, string>;
    timestamp: string;
}
/**
 * Stripe webhook event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeWebhookEventData {
    eventId: string;
    eventType: string;
    data: any;
    livemode: boolean;
    timestamp: string;
}
/**
 * Stripe event data interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface StripeEventData {
    eventId?: string;
    eventType?: string;
    customerId?: string;
    subscriptionId?: string;
    amount?: number;
    currency?: string;
    status?: string;
    metadata?: Record<string, any>;
    timestamp: string;
}

/**
 * @fileoverview Firebase Types
 * @description Type definitions for Firebase integration. Defines Firestore timestamp interface and date value types for Firebase compatibility without requiring the Firebase Admin SDK.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Interface mimicking Firebase Timestamp for type compatibility
 * without requiring the actual Firebase Admin SDK
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FirestoreTimestamp {
    seconds: number;
    nanoseconds: number;
    toDate(): Date;
    toMillis(): number;
    isEqual(other: FirestoreTimestamp): boolean;
    valueOf(): string;
}
/**
 * Represents a date value in various formats accepted by Firebase.
 * Can be a JavaScript Date, a Firestore Timestamp, or an ISO 8601 string.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type DateValue = Date | FirestoreTimestamp | string;
/**
 * Firebase configuration object
 * Contains the configuration needed to initialize a Firebase app
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FirebaseConfig {
    /** Firebase API key */
    apiKey: string;
    /** Firebase authentication domain */
    authDomain: string;
    /** Firebase project ID */
    projectId: string;
    /** Firebase storage bucket URL (optional) */
    storageBucket?: string;
    /** Firebase messaging sender ID (optional) */
    messagingSenderId?: string;
    /** Firebase app ID (optional) */
    appId?: string;
    /** Firebase measurement ID for analytics (optional) */
    measurementId?: string;
}
/**
 * Options for Firebase functions call with abort support
 * Allows for cancellable Firebase function calls
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FirebaseCallOptions {
    /** Optional key for the abort controller */
    abortKey?: string;
    /** Optional external abort signal to link with internal controller */
    externalSignal?: AbortSignal;
    /** Flag for public function calls */
    public?: boolean;
    /** HTTP callable timeout in milliseconds */
    timeout?: number;
}
/**
 * Interface for Firebase uniqueness validation
 * Used to check if a value would create a duplicate in a collection
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FirestoreUniqueConstraintValidator {
    /**
     * Checks if a value would cause a duplicate in a given collection
     *
     * @param collection - The collection to check
     * @param field - The field to check
     * @param value - The value to check
     * @param currentDocId - The ID of the current document (for updates)
     * @returns A promise that resolves to true if a duplicate exists
     */
    checkDuplicate: (collection: string, field: string, value: any, currentDocId?: string) => Promise<boolean>;
}

/**
 * @fileoverview Hook Types
 * @description Type definitions for hook types. Defines options for listing operations, pagination, filtering, and sorting used by hooks.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Options for listing operations.
 * Used to customize the behavior of list hooks.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ListOptions {
    /** The page number (1-indexed) to fetch */
    page?: number;
    /** The number of items per page */
    pageSize?: number;
    /** Filters to apply to the list */
    filters?: Record<string, any>;
    /** Sorting options */
    sort?: {
        /** The field to sort by */
        field: string;
        /** The direction to sort in */
        direction: 'asc' | 'desc';
    };
}
/**
 * Standard response for list operations.
 * Used by list hooks to return paginated data.
 * @template T - The type of items in the list
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ListResponse<T> {
    /** The items in the current page */
    items: T[];
    /** The total number of items across all pages */
    total: number;
    /** The current page number */
    page: number;
    /** The number of items per page */
    pageSize: number;
    /** Whether there are more pages to fetch */
    hasMore: boolean;
}
/**
 * Standard response for mutations.
 * Used by create, update, and delete hooks to return the result of the operation.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface MutationResponse {
    /** The ID of the affected entity */
    id: string;
    /** Additional fields that may be returned by the mutation */
    [key: string]: any;
}

/**
 * @fileoverview Function Types
 * @description Type definitions for function types. Defines schema metadata, function request/response types, and function-related interfaces.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Valid operators for database queries
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type WhereOperator = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'array-contains' | 'array-contains-any' | 'in' | 'not-in';
/**
 * Firestore where clause tuple
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type WhereClause = [string, WhereOperator, any];
/**
 * Firestore orderBy clause tuple
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OrderByClause = [string, 'asc' | 'desc'];
/**
 * Represents a reference to another document.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface Reference {
    /** The collection containing the referenced document */
    collection: string;
    /** The ID of the referenced document */
    document: string;
    /** The field in the referenced document */
    field: string;
}
/**
 * Metadata fields for an entity.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface EntityMetadata {
    /** ISO 8601 timestamp when the entity was created */
    createdAt: string;
    /** ISO 8601 timestamp when the entity was last updated */
    updatedAt: string;
    /** ID of the user who created the entity */
    createdById: string;
    /** ID of the user who last updated the entity */
    updatedById: string;
}
/**
 * Utility type that adds metadata to a document.
 * @template T - The base document type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type WithMetadata<T> = T & EntityMetadata;
/**
 * Data required for creating an entity
 * @template T - The entity type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CreateEntityData<T extends Record<string, any>> {
    /** The schema to validate against */
    schema: dndevSchema<T>;
    /** The entity data to create */
    payload: T;
    /** Optional idempotency key for preventing duplicate operations */
    idempotencyKey?: string;
}
/**
 * Data required for updating an entity
 * @template T - The entity type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UpdateEntityData<T extends Record<string, any>> {
    /** The schema to validate against */
    schema: dndevSchema<T>;
    /** The ID of the entity to update */
    id: string;
    /** The partial entity data to update */
    payload: Partial<T>;
    /** Optional idempotency key for preventing duplicate operations */
    idempotencyKey?: string;
}
/**
 * Data required for getting an entity
 * @template T - The entity type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface GetEntityData<T extends Record<string, any>> {
    /** The schema to validate against */
    schema: dndevSchema<T>;
    /** The ID of the entity to get */
    id: string;
}
/**
 * Data required for listing entities
 * @template T - The entity type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ListEntityData<T extends Record<string, any>> extends ListOptions {
    /** The schema to validate against */
    schema: dndevSchema<T>;
}
/**
 * Supported function platforms
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FunctionPlatform = 'firebase' | 'vercel' | 'aws' | 'custom';
/**
 * Function call configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionCallConfig {
    /** Platform to use for function calls */
    platform: FunctionPlatform;
    /** Region for the function (platform-specific) */
    region?: string;
    /** Default timeout in milliseconds */
    timeout?: number;
    /** Number of retry attempts */
    retries?: number;
    /** Base URL for custom platforms */
    baseUrl?: string;
}
/**
 * Function call options
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionCallOptions {
    /** Whether this is a public function call (no auth required) */
    public?: boolean;
    /** Request timeout in milliseconds */
    timeout?: number;
    /** Number of retry attempts */
    retries?: number;
    /** Abort signal for request cancellation */
    signal?: AbortSignal;
    /** Whether to cache the response */
    cache?: boolean;
    /** Cache stale time in milliseconds */
    staleTime?: number;
    /** Custom headers */
    headers?: Record<string, string>;
}
/**
 * Function response wrapper
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionResponse<T = any> {
    /** Response data */
    data: T;
    /** Whether the call was successful */
    success: boolean;
    /** Error message if any */
    error?: string;
    /** Response metadata */
    metadata?: {
        platform: FunctionPlatform;
        duration: number;
        cached: boolean;
        timestamp: string;
    };
}
/**
 * Function error details
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionError {
    /** Error code */
    code: string;
    /** Error message */
    message: string;
    /** Additional error details */
    details?: any;
    /** Platform-specific error information */
    platform?: {
        name: FunctionPlatform;
        errorCode?: string;
        errorMessage?: string;
    };
}
/**
 * Function call result
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FunctionCallResult<T> = {
    success: true;
    data: T;
    error?: never;
} | {
    success: false;
    data?: never;
    error: FunctionError;
};
/**
 * Function client interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionClient {
    /** Call a function */
    callFunction<TData>(functionName: string, params?: object, schema?: v.BaseSchema<unknown, TData, v.BaseIssue<unknown>>, options?: FunctionCallOptions): Promise<TData>;
    /** Get client configuration */
    getConfig(): FunctionCallConfig;
    /** Update client configuration */
    updateConfig(config: Partial<FunctionCallConfig>): void;
}
/**
 * Function loader interface for lazy loading
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionLoader {
    /** Load the functions system */
    load(): Promise<FunctionSystem>;
    /** Check if system is loaded */
    isLoaded(): boolean;
    /** Get loaded system (throws if not loaded) */
    getSystem(): FunctionSystem;
}
/**
 * Result type for useFunctionsQuery hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UseFunctionsQueryResult<TData> {
    /** Query data */
    data: TData | undefined;
    /** Whether the query is loading */
    isLoading: boolean;
    /** Whether the query encountered an error */
    isError: boolean;
    /** Error details if any */
    error: FunctionError | null;
    /** Whether the query is currently fetching (includes background refetch) */
    isFetching: boolean;
    /** Refetch the query */
    refetch: () => Promise<void>;
}
/**
 * Result type for useFunctionsMutation hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UseFunctionsMutationResult<TData, TVariables> {
    /** Execute the mutation */
    mutate: (variables: TVariables) => void;
    /** Execute the mutation and return a promise */
    mutateAsync: (variables: TVariables) => Promise<TData>;
    /** Whether the mutation is in progress */
    isLoading: boolean;
    /** Whether the mutation encountered an error */
    isError: boolean;
    /** Whether the mutation succeeded */
    isSuccess: boolean;
    /** Error details if any */
    error: FunctionError | null;
    /** Mutation result data */
    data: TData | undefined;
    /** Reset the mutation state */
    reset: () => void;
}
/**
 * Result type for useFunctionsCall hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UseFunctionsCallResult<TData> {
    /** Execute the function call */
    call: (params?: object) => Promise<TData>;
    /** Whether the call is in progress */
    isLoading: boolean;
    /** Whether the call encountered an error */
    isError: boolean;
    /** Error details if any */
    error: FunctionError | null;
    /** Call result data */
    data: TData | undefined;
}
/**
 * Complete functions system interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionSystem {
    /** Function client */
    client: FunctionClient;
    /** React Query hooks */
    hooks: {
        useFunctionsQuery: <TData = unknown>(functionName: string, params?: object, schema?: v.BaseSchema<unknown, TData, v.BaseIssue<unknown>>, options?: UseFunctionsQueryOptions<TData>) => UseFunctionsQueryResult<TData>;
        useFunctionsMutation: <TData = unknown, TVariables = object>(functionName: string, schema?: v.BaseSchema<unknown, TData, v.BaseIssue<unknown>>, options?: UseFunctionsMutationOptions<TData, TVariables>) => UseFunctionsMutationResult<TData, TVariables>;
        useFunctionsCall: <TData = unknown>(functionName: string, options?: FunctionCallOptions) => UseFunctionsCallResult<TData>;
    };
    /** Direct call function */
    callFunction: FunctionClient['callFunction'];
}
/**
 * React Query options for functions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UseFunctionsQueryOptions<TData> {
    /** Whether the query is enabled */
    enabled?: boolean;
    /** Time until data is considered stale */
    staleTime?: number;
    /** Time until inactive data is garbage collected */
    gcTime?: number;
    /** Number of retry attempts */
    retry?: number;
    /** Whether to keep previous data while fetching */
    keepPreviousData?: boolean;
    /** Whether to refetch on window focus */
    refetchOnWindowFocus?: boolean;
    /** Callback for successful queries */
    onSuccess?: (data: TData) => void;
    /** Callback for failed queries */
    onError?: (error: FunctionError) => void;
}
/**
 * React Query mutation options for functions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface UseFunctionsMutationOptions<TData, TVariables> {
    /** Number of retry attempts */
    retry?: number;
    /** Callback before mutation */
    onMutate?: (variables: TVariables) => void | Promise<void>;
    /** Callback for successful mutations */
    onSuccess?: (data: TData, variables: TVariables) => void;
    /** Callback for failed mutations */
    onError?: (error: FunctionError, variables: TVariables) => void;
    /** Callback after mutation (success or failure) */
    onSettled?: (data: TData | undefined, error: FunctionError | null, variables: TVariables) => void;
}
/**
 * Function schema definition
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionSchema<TInput = any, TOutput = any> {
    /** Input validation schema */
    input?: v.BaseSchema<unknown, TInput, v.BaseIssue<unknown>>;
    /** Output validation schema */
    output?: v.BaseSchema<unknown, TOutput, v.BaseIssue<unknown>>;
    /** Function name */
    name: string;
    /** Whether this is a public function */
    public?: boolean;
    /** Function description */
    description?: string;
}
/**
 * Predefined function schemas
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionSchemas {
    /** Auth-related functions */
    auth: {
        getUserProfile: FunctionSchema<{
            userId: string;
        }, Record<string, unknown>>;
        updateUserProfile: FunctionSchema<Record<string, unknown>, Record<string, unknown>>;
        refreshToken: FunctionSchema<Record<string, never>, Record<string, unknown>>;
    };
    /** Billing-related functions */
    billing: {
        createCheckoutSession: FunctionSchema<Record<string, unknown>, Record<string, unknown>>;
        refreshSubscriptionStatus: FunctionSchema<Record<string, never>, Record<string, unknown>>;
        processPaymentSuccess: FunctionSchema<Record<string, unknown>, Record<string, unknown>>;
    };
    /** Generic CRUD functions */
    crud: {
        createEntity: FunctionSchema<Record<string, unknown>, Record<string, unknown>>;
        updateEntity: FunctionSchema<Record<string, unknown>, Record<string, unknown>>;
        deleteEntity: FunctionSchema<{
            id: string;
        }, Record<string, unknown>>;
        getEntity: FunctionSchema<{
            id: string;
        }, Record<string, unknown>>;
        listEntities: FunctionSchema<Record<string, unknown>, Record<string, unknown>[]>;
    };
}
/**
 * Function call context
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionCallContext {
    /** User authentication token */
    token?: string;
    /** User ID */
    userId?: string;
    /** Request ID for tracking */
    requestId?: string;
    /** Additional context data */
    metadata?: Record<string, any>;
}
/**
 * Function client factory options
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionClientFactoryOptions {
    /** Default configuration */
    config?: Partial<FunctionCallConfig>;
    /** Authentication token provider */
    getToken?: () => Promise<string | null>;
    /** Error handler */
    onError?: (error: FunctionError) => void;
    /** Request interceptor */
    onRequest?: (functionName: string, params: any) => void;
    /** Response interceptor */
    onResponse?: (functionName: string, response: any) => void;
}
/**
 * Memory allocation options for Cloud Functions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FunctionMemory = '128MB' | '256MB' | '512MB' | '1GB' | '2GB' | '4GB' | '8GB';
/**
 * Function trigger types
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FunctionTrigger = 'callable' | 'http' | 'pubsub' | 'firestore' | 'auth' | 'storage' | 'scheduled';
/**
 * Function-level deployment metadata
 * @description Per-function configuration for Firebase deployment (like PageMeta for pages)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionMeta {
    /** Custom entry point name (defaults to export name) */
    entryPoint?: string;
    /** Deployment regions (overrides app defaults) */
    region?: string[];
    /** Platform version */
    platform?: 'gcfv1' | 'gcfv2';
    /** Category label for organization */
    category?: 'auth' | 'crud' | 'analytics' | 'scheduled' | 'webhook' | string;
    /** Additional labels */
    labels?: Record<string, string>;
    /** Trigger type (defaults to 'callable') */
    trigger?: FunctionTrigger;
    /** For scheduled functions - cron expression */
    schedule?: string;
    /** Memory allocation */
    memory?: FunctionMemory;
    /** Timeout in seconds */
    timeoutSeconds?: number;
    /** Minimum instances (for cold start optimization) */
    minInstances?: number;
    /** Maximum instances */
    maxInstances?: number;
    /** Secret environment variable names (synced via sync-secrets, read via defineSecret) */
    secrets?: string[];
}
/**
 * CRUD entity configuration for auto-generation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CrudConfig {
    /** Entity collection names to generate CRUD for */
    entities: string[];
    /** Override defaults for all CRUD functions */
    defaults?: Partial<FunctionMeta>;
}
/**
 * App-level defaults for all functions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionDefaults {
    /** Default deployment regions */
    region?: string[];
    /** Default platform version */
    platform?: 'gcfv1' | 'gcfv2';
    /** App label for all functions */
    labels?: Record<string, string>;
    /** Default memory allocation */
    memory?: FunctionMemory;
    /** Default timeout in seconds */
    timeoutSeconds?: number;
}
/**
 * Complete functions configuration for an app
 * @description Single config file pattern for functions.yaml generation
 *
 * @example
 * ```typescript
 * export const functionsConfig: FunctionsConfig = {
 *   defaults: {
 *     region: ['europe-west1'],
 *     platform: 'gcfv2',
 *     labels: { app: 'myapp' },
 *   },
 *   functions: {
 *     setCustomClaims: { category: 'auth' },
 *     getDashboardMetrics: { category: 'analytics', memory: '512MB' },
 *   },
 *   crud: {
 *     entities: ['car', 'customer', 'inquiry'],
 *   },
 * };
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionsConfig {
    /** App-level defaults applied to all functions */
    defaults?: FunctionDefaults;
    /** Static functions configuration (non-CRUD) */
    functions?: Record<string, FunctionMeta>;
    /** CRUD auto-generation configuration */
    crud?: CrudConfig;
}
/**
 * Generated function endpoint entry (for YAML output)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface FunctionEndpoint {
    /** Function name (key in endpoints object) */
    name: string;
    /** Deployment regions */
    region: string[];
    /** Platform version */
    platform: 'gcfv1' | 'gcfv2';
    /** Trigger configuration */
    callableTrigger?: Record<string, never>;
    httpsTrigger?: Record<string, never>;
    scheduleTrigger?: {
        schedule: string;
    };
    /** Entry point in bundled code */
    entryPoint: string;
    /** Labels for organization */
    labels: Record<string, string>;
    /** Memory allocation */
    memory?: string;
    /** Timeout */
    timeoutSeconds?: number;
    /** Min instances */
    minInstances?: number;
    /** Max instances */
    maxInstances?: number;
    /** Secret environment variables */
    secretEnvironmentVariables?: Array<{
        key: string;
    }>;
}

/**
 * @fileoverview I18n Types
 * @description Type definitions for internationalization. Defines entity translations, i18n configuration types, and translation-related interfaces.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Entity translation interface
 * Maps entity field names to their translated labels and hints
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface EntityTranslations {
    /** Translated field labels */
    fields: Record<string, string>;
    /** Translated field hints/descriptions */
    hints: Record<string, string>;
    /** Translated validation error messages */
    validations?: Record<string, string>;
    /** Translated placeholder text */
    placeholders?: Record<string, string>;
}
/**
 * Common translation interface for shared UI elements
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CommonTranslations {
    /** Action button translations */
    actions: {
        create: string;
        update: string;
        delete: string;
        cancel: string;
        confirm: string;
    };
    /** Error message translations */
    errors: Record<string, string>;
    /** Common label translations */
    labels: Record<string, string>;
}
/**
 * Translation options interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface TranslationOptions {
    /** Language code (e.g., 'en', 'fr') */
    lng: string;
    /** Optional namespace array */
    ns?: string[];
    /** Fallback language code */
    fallbackLng?: string;
}
/**
 * Supported language codes
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type SupportedLanguage = string;
/**
 * Interface for language information
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface LanguageInfo {
    /** ISO 639-1 language code (e.g., 'en', 'fr') */
    code: string;
    /** Native name of the language (e.g., 'English', 'Français') */
    name: string;
}
/**
 * Language data type — single source of truth for language metadata.
 * Used by i18n constants, language store, and language selector components.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface LanguageData {
    /** BCP-47 language code (e.g., 'en', 'fr', 'ar-ma') */
    id: string;
    /** English display name */
    name: string;
    /** Native script display name */
    nativeName: string;
    /** Override flag code when it differs from the language id */
    flagCode?: string;
    /** ISO 3166-1 alpha-2 country code */
    countryCode?: string;
    /** International dialing code (e.g., '+33') */
    dialCode?: string;
    /** Human-readable country name for display labels */
    countryName?: string;
}
/**
 * Interface for configurations to initialize the i18n system
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface I18nConfig {
    /** Patterns for eager namespaces */
    eagerPatterns: string[];
    /** Patterns for lazy namespaces */
    lazyPatterns: string[];
    /** App namespace patterns (eagerly loaded) */
    eagerNamespaces: string[];
    /** Custom namespace patterns for arbitrary use cases (lazily loaded) */
    lazyNamespaces: string[];
    /** Performance options */
    performance: {
        /** Maximum number of translations to keep in memory cache */
        cacheSize: number;
        /** Time to live for cached errors in milliseconds */
        errorCacheTTL: number;
        /** Timeout for loading operations in milliseconds */
        loadTimeout: number;
    };
    /** Language options */
    languages: {
        /** List of supported language codes */
        supported: string[];
        /** Default language code */
        default: string;
        /** Fallback language code */
        fallback: string;
    };
    /** Debug mode flag */
    debug: boolean;
    /** Protocol name for virtual loader (default: 'virtual') */
    virtualProtocol: string;
    /** Additional i18next initialization options */
    i18nextOptions: Partial<InitOptions>;
    /** Force production mode */
    forceProduction: boolean;
    /** Force development mode */
    forceDevelopment: boolean;
}
/**
 * Interface representing the structure of a translations resource
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface TranslationResource {
    /** Language code (e.g., 'en', 'fr') */
    [language: string]: {
        /** Namespace (e.g., 'common', 'auth') */
        [namespace: string]: Record<string, any>;
    };
}
/**
 * Enhanced options for useTranslation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type UseTranslationOptionsEnhanced<KPrefix> = Parameters<typeof useTranslation>[1] & {
    /** Whether this namespace is an app namespace */
    appNamespace?: boolean;
};
/**
 * Props for the I18nProvider component
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface I18nProviderProps {
    /** Child components to render */
    children: ReactNode;
    /** Initial configuration */
    config?: Partial<I18nConfig>;
    /** Initial language to use */
    fallbackLng?: string;
    /** Pre-initialized i18n instance */
    i18n?: any;
    /** Optional callback when i18n initialization completes */
    onInitialized?: (i18n: any) => void;
    /** Health monitoring flag (defaults to true) */
    healthMonitoring?: boolean;
    /** Loading component to display while initializing */
    loadingComponent?: ReactNode;
    /** Error component to display if initialization fails */
    errorComponent?: ReactNode;
}
/**
 * Information about a cached error
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CachedError {
    /** The error object */
    error: Error;
    /** Timestamp when the error occurred */
    timestamp: number;
}
/**
 * Custom read callback for i18next backend
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ReadCallback = (err: any, data: any) => void;

/**
 * @fileoverview Breakpoint Types
 * @description Breakpoint type definitions for responsive design. Defines the standard breakpoints used throughout the framework for responsive layout and component behavior.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Breakpoint type definition for responsive design
 *
 * Defines the standard breakpoints used throughout the framework
 * for responsive layout and component behavior.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type Breakpoint = 'mobile' | 'tablet' | 'laptop' | 'desktop';
/**
 * Breakpoint pixel values
 *
 * Standard breakpoint thresholds used for responsive design.
 * These values match the CSS variables in layout-variables.css
 * and are used by the theme store and layout system.
 */
/**
 * Breakpoint threshold values for calculation
 *
 * These are the actual breakpoint boundaries used for responsive logic.
 * Each value represents the minimum width for that breakpoint.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const BREAKPOINT_THRESHOLDS: {
    readonly mobile: 0;
    readonly tablet: 768;
    readonly laptop: 1024;
    readonly desktop: 1440;
};
/**
 * Breakpoint pixel ranges
 *
 * Defines the pixel ranges for each breakpoint to help with
 * responsive design calculations and media queries.
 * These ranges match the CSS media queries and store logic.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const BREAKPOINT_RANGES: Record<Breakpoint, {
    min: number;
    max: number;
}>;
/**
 * Breakpoint utilities interface
 *
 * Provides computed breakpoint state and helper methods
 * for responsive design logic.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BreakpointUtils {
    /** Current active breakpoint */
    current: Breakpoint;
    /** Current window width in pixels */
    width: number;
    /** Current window height in pixels */
    height: number;
    /** Whether current viewport is mobile (0-767px) */
    isMobile: boolean;
    /** Whether current viewport is tablet (768-1023px) */
    isTablet: boolean;
    /** Whether current viewport is laptop (1024-1439px) */
    isLaptop: boolean;
    /** Whether current viewport is desktop (1440px+) */
    isDesktop: boolean;
    /** Whether current viewport is mobile OR tablet (< 1024px) */
    isMobileOrTablet: boolean;
    /** Whether current viewport is laptop OR desktop (>= 1024px) */
    isLaptopOrDesktop: boolean;
}
/**
 * Get breakpoint from window width
 *
 * @param width - Window width in pixels
 * @returns The corresponding breakpoint
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function getBreakpointFromWidth(width: number): Breakpoint;
/**
 * Check if a breakpoint matches the current width
 *
 * @param width - Window width in pixels
 * @param breakpoint - Target breakpoint to check
 * @returns Whether the width matches the breakpoint
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function isBreakpoint(width: number, breakpoint: Breakpoint): boolean;
/**
 * Get breakpoint utilities from window dimensions
 *
 * @param width - Window width in pixels
 * @param height - Window height in pixels
 * @returns Computed breakpoint utilities
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function getBreakpointUtils(width: number, height: number): BreakpointUtils;

/**
 * @fileoverview Legal Configuration Types
 * @description Type definitions for legal pages configuration (Terms, Privacy, Legal Notice)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Company/Publisher Information
 *
 * Information about the company or individual publishing the website
 */
interface LegalCompanyInfo {
    /**
     * Full legal name of the company or individual
     * @example "AMBROISE PARK Consulting"
     * @example "John Doe"
     */
    name: string;
    /**
     * Short name or abbreviation
     * @example "APC"
     * @example "ACME Inc."
     */
    shortName?: string;
    /**
     * Legal status/form of the company
     * @example "SARL" (France - Limited Liability Company)
     * @example "SAS" (France - Simplified Joint-Stock Company)
     * @example "LLC" (USA - Limited Liability Company)
     * @example "GmbH" (Germany)
     * @example "Ltd" (UK)
     */
    legalStatus?: string;
    /**
     * Company registration number
     * @description Required in many countries for legal compliance
     * @example "123 456 789 00010" (France - SIRET number)
     * @example "12345678" (UK - Company Number)
     * @example "123-45-6789" (USA - EIN)
     */
    registrationNumber?: string;
    /**
     * VAT/Tax identification number
     * @description Required for EU businesses and many other jurisdictions
     * @example "FR12345678901" (France)
     * @example "DE123456789" (Germany)
     * @example "GB123456789" (UK)
     */
    vatNumber?: string;
    /**
     * Share capital (for companies)
     * @description Required to be disclosed in some jurisdictions (e.g., France)
     * @example "10,000 EUR"
     * @example "50,000 USD"
     */
    shareCapital?: string;
}
/**
 * Contact Information
 *
 * Various contact points for legal, support, and privacy inquiries
 */
interface LegalContactInfo {
    /**
     * Registered office address
     * @description Physical address where the company is legally registered
     * @example "123 rue de la Paix, 75001 Paris, France"
     * @example "1 Main Street, Suite 100, New York, NY 10001, USA"
     */
    address: string;
    /**
     * General legal contact email
     * @description For legal inquiries and notices
     * @example "legal@company.com"
     */
    email: string;
    /**
     * Contact phone number
     * @description Optional but recommended for legal compliance
     * @example "+33 1 23 45 67 89"
     * @example "+1 (555) 123-4567"
     */
    phone?: string;
    /**
     * Support email for customer inquiries
     * @example "support@company.com"
     */
    supportEmail: string;
    /**
     * Privacy-specific email
     * @description For privacy policy and data protection inquiries
     * @example "privacy@company.com"
     */
    privacyEmail: string;
    /**
     * Data Protection Officer (DPO) email
     * @description Required for GDPR compliance if you process significant personal data
     * @example "dpo@company.com"
     */
    dpoEmail: string;
}
/**
 * Publication Director Information
 *
 * Information about the person responsible for the website's content
 * Required by law in France ("Directeur de la publication")
 */
interface LegalDirectorInfo {
    /**
     * Full name of the publication director
     * @description The person legally responsible for the website's content
     * @example "John Doe"
     * @example "Jane Smith"
     */
    name: string;
    /**
     * Role/title of the publication director
     * @example "CEO"
     * @example "Directeur Général"
     * @example "Managing Director"
     */
    role?: string;
}
/**
 * Hosting Provider Information
 *
 * Information about where and how the website is hosted
 * Required by law in many jurisdictions including France
 */
interface LegalHostingInfo {
    /**
     * Name of the hosting provider
     * @example "Firebase Hosting by Google"
     * @example "AWS (Amazon Web Services)"
     * @example "OVH"
     */
    provider: string;
    /**
     * Hosting provider's address
     * @description Physical address of the hosting company
     * @example "Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA"
     */
    address?: string;
    /**
     * Hosting provider contact information
     * @description URL or email to contact the hosting provider
     * @example "https://firebase.google.com/support"
     * @example "support@hostingprovider.com"
     */
    contact?: string;
}
/**
 * Legal Jurisdiction Information
 *
 * Information about the legal jurisdiction and dispute resolution
 */
interface LegalJurisdictionInfo {
    /**
     * Country or jurisdiction where the company operates
     * @example "France"
     * @example "United States"
     * @example "United Kingdom"
     */
    country: string;
    /**
     * Arbitration organization for dispute resolution
     * @example "Centre de Médiation et d'Arbitrage de Paris"
     * @example "American Arbitration Association"
     * @example "International Chamber of Commerce"
     */
    arbitrationOrg?: string;
    /**
     * Location where arbitration would take place
     * @example "Paris, France"
     * @example "New York, NY"
     */
    arbitrationLocation?: string;
}
/**
 * Website Information
 */
interface LegalWebsiteInfo {
    /**
     * Main website URL
     * @example "https://company.com"
     * @example "https://www.example.com"
     */
    url: string;
}
/**
 * Optional Sections Configuration for Legal Pages
 */
interface LegalSectionsConfig {
    /**
     * Terms of Service optional sections
     */
    terms?: {
        /** Include children-specific provisions (COPPA, etc.) */
        children?: boolean;
        /** Include international users provisions */
        international?: boolean;
        /** Include California-specific provisions (CCPA, etc.) */
        california?: boolean;
        /** Include EU-specific provisions */
        eu?: boolean;
    };
    /**
     * Privacy Policy optional sections
     */
    privacy?: {
        /** Include children's privacy provisions (COPPA, etc.) */
        children?: boolean;
        /** Include international data transfer provisions */
        international?: boolean;
        /** Include California privacy rights (CCPA, etc.) */
        california?: boolean;
        /** Include EU privacy provisions (GDPR) */
        eu?: boolean;
    };
    /**
     * Legal Notice optional sections
     */
    legalNotice?: {
        /** Include intellectual property notice */
        intellectualProperty?: boolean;
        /** Include personal data reference/link to privacy policy */
        personalData?: boolean;
        /** Include cookies reference/link to privacy policy */
        cookies?: boolean;
    };
}
/**
 * Complete Legal Configuration
 *
 * @description
 * Centralized configuration for all legal pages (Terms, Privacy, Legal Notice).
 * Configure this once in your app's config/legal.ts file.
 *
 * @example
 * ```typescript
 * import type { LegalConfig } from '@donotdev/types';
 *
 * export const legalConfig: LegalConfig = {
 *   company: {
 *     name: 'ACME Corporation',
 *     legalStatus: 'LLC',
 *     registrationNumber: '123456789',
 *     vatNumber: 'US123456789',
 *   },
 *   contact: {
 *     address: '123 Main St, City, State 12345, Country',
 *     email: 'legal@acme.com',
 *     supportEmail: 'support@acme.com',
 *     privacyEmail: 'privacy@acme.com',
 *     dpoEmail: 'dpo@acme.com',
 *   },
 *   director: {
 *     name: 'John Doe',
 *     role: 'CEO',
 *   },
 *   hosting: {
 *     provider: 'Firebase Hosting by Google',
 *     contact: 'https://firebase.google.com/support',
 *   },
 *   jurisdiction: {
 *     country: 'United States',
 *   },
 *   website: {
 *     url: 'https://acme.com',
 *   },
 * };
 * ```
 */
interface LegalConfig {
    /** Company/Publisher information */
    company: LegalCompanyInfo;
    /** Contact information */
    contact: LegalContactInfo;
    /** Publication director information */
    director: LegalDirectorInfo;
    /** Hosting provider information */
    hosting: LegalHostingInfo;
    /** Legal jurisdiction information */
    jurisdiction: LegalJurisdictionInfo;
    /** Website information */
    website: LegalWebsiteInfo;
    /** Sections configuration for legal pages */
    sections: LegalSectionsConfig;
    /** Last updated dates (ISO strings) for each legal page */
    lastUpdated?: {
        /** Terms of Service last updated date (ISO string) */
        terms?: string;
        /** Privacy Policy last updated date (ISO string) */
        privacy?: string;
        /** Legal Notice last updated date (ISO string) */
        legalNotice?: string;
    };
}

/**
 * @fileoverview OAuth Constants
 * @description Constants for OAuth domain. Defines GitHub repository permission levels and OAuth-related constants.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * GitHub repository permission levels (runtime constants)
 * Keep in sync with GitHub API scopes/permissions.
 */
declare const GITHUB_PERMISSION_LEVELS: readonly ["pull", "push", "admin", "maintain", "triage"];
/**
 * OAuth purpose type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthPurpose = 'authentication' | 'api-access';

/**
 * @fileoverview OAuth Schema Definitions
 * @description Schema definitions for OAuth domain. Defines Valibot schemas for GitHub repository configuration, permission levels, and OAuth-related data structures.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Schema for GitHub repository configuration
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const githubRepoConfigSchema: v.ObjectSchema<{
    readonly owner: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository owner is required">]>;
    readonly repo: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository name is required">]>;
}, undefined>;
/**
 * Schema for GitHub access permission levels
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const githubPermissionSchema: v.PicklistSchema<[string, ...string[]], undefined>;
/**
 * Schema for granting GitHub repository access
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const grantGitHubAccessSchema: v.ObjectSchema<{
    readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "User ID is required">]>;
    readonly githubUsername: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "GitHub username is required">]>;
    readonly repoConfig: v.ObjectSchema<{
        readonly owner: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository owner is required">]>;
        readonly repo: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository name is required">]>;
    }, undefined>;
    readonly permission: v.OptionalSchema<v.PicklistSchema<[string, ...string[]], undefined>, "push">;
    readonly customClaims: v.OptionalSchema<v.RecordSchema<v.StringSchema<undefined>, v.AnySchema, undefined>, undefined>;
}, undefined>;
/**
 * Schema for revoking GitHub repository access
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const revokeGitHubAccessSchema: v.ObjectSchema<{
    readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "User ID is required">]>;
    readonly githubUsername: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "GitHub username is required">]>;
    readonly repoConfig: v.ObjectSchema<{
        readonly owner: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository owner is required">]>;
        readonly repo: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository name is required">]>;
    }, undefined>;
}, undefined>;
/**
 * Schema for checking GitHub repository access
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const checkGitHubAccessSchema: v.ObjectSchema<{
    readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "User ID is required">]>;
    readonly githubUsername: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "GitHub username is required">]>;
    readonly repoConfig: v.ObjectSchema<{
        readonly owner: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository owner is required">]>;
        readonly repo: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Repository name is required">]>;
    }, undefined>;
}, undefined>;
/**
 * TypeScript type exports for GitHub access schemas
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type GrantGitHubAccessRequest = v.InferOutput<typeof grantGitHubAccessSchema>;
/**
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type RevokeGitHubAccessRequest = v.InferOutput<typeof revokeGitHubAccessSchema>;
/**
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type CheckGitHubAccessRequest = v.InferOutput<typeof checkGitHubAccessSchema>;
/**
 * Schema for OAuth token exchange requests
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const exchangeTokenSchema: v.ObjectSchema<{
    readonly provider: v.BaseSchema<unknown, OAuthPartnerId, v.BaseIssue<unknown>>;
    readonly purpose: v.BaseSchema<unknown, OAuthPurpose, v.BaseIssue<unknown>>;
    readonly code: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Authorization code is required">]>;
    readonly redirectUri: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, "Valid redirect URI is required">]>;
    readonly codeVerifier: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly state: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly instance: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, undefined>]>, undefined>;
}, undefined>;
/**
 * Schema for refreshing OAuth token
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const refreshTokenSchema: v.ObjectSchema<{
    readonly provider: v.BaseSchema<unknown, OAuthPartnerId, v.BaseIssue<unknown>>;
    readonly refreshToken: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "Refresh token is required">]>;
    readonly redirectUri: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.UrlAction<string, "Valid redirect URI is required">]>;
}, undefined>;
/**
 * Schema for disconnecting OAuth
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const disconnectOAuthSchema: v.ObjectSchema<{
    readonly provider: v.BaseSchema<unknown, OAuthPartnerId, v.BaseIssue<unknown>>;
}, undefined>;
/**
 * Schema for getting OAuth connections
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const getConnectionsSchema: v.ObjectSchema<{
    readonly userId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, "User ID is required">]>;
}, undefined>;

/**
 * @fileoverview OAuth Types
 * @description Type definitions for OAuth domain. Defines base credentials, user profiles, OAuth partner types, and OAuth-related interfaces.
 * Uses unified FeatureStatus enum for feature state management.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Base credentials interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseCredentials {
    expiresAt?: number;
    scope?: string[];
}
/**
 * Base user profile interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseUserProfile {
    id: string;
    name?: string;
    username?: string;
    email?: string;
    photoURL?: string;
}
/**
 * Base partner state interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BasePartnerState {
    config: any;
    error: Error | null;
}
/**
 * OAuth credentials interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthCredentials extends BaseCredentials {
    accessToken: string;
    refreshToken?: string;
    idToken?: string;
    tokenType?: string;
    expiresIn?: number;
}
/**
 * OAuth partner result interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthPartnerResult extends PartnerResult {
    partnerId: OAuthPartnerId;
    purpose: OAuthPurpose;
    credentials?: OAuthCredentials;
}
/**
 * OAuth partner state interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthPartnerState extends PartnerConnectionState {
    partnerId: OAuthPartnerId;
    config: OAuthPartner;
    credentials: OAuthCredentials | null;
}
/**
 * OAuth API request options interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthApiRequestOptions extends RequestInit {
    autoRefresh?: boolean;
    requireConnection?: boolean;
}
/**
 * OAuth connection status type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error' | 'expired';
/**
 * OAuth result type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthResult = {
    success: true;
    partner: string;
    accessToken: string;
    refreshToken?: string;
    idToken?: string;
    expiresIn?: number;
    scope?: string;
    tokenType?: string;
    profile?: Record<string, any>;
} | {
    success: false;
    error: string;
    errorDescription?: string;
    attemptedPartner?: string;
};
/**
 * Exchange token parameters interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ExchangeTokenParams {
    provider: OAuthPartnerId;
    purpose: OAuthPurpose;
    code: string;
    redirectUri: string;
    codeVerifier?: string;
}
/**
 * OAuth connection info interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthConnectionInfo {
    id: string;
    userId: string;
    provider: OAuthPartnerId;
    purpose: OAuthPurpose;
    connected: boolean;
    createdAt: string;
    updatedAt: string;
    lastUsed?: string;
    credentials?: OAuthCredentials;
    profile?: BaseUserProfile;
}
/**
 * OAuth connection interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthConnection {
    partnerId: OAuthPartnerId;
    status: OAuthConnectionStatus;
    connectedAt?: Date;
    lastError?: string;
    userData?: any;
    lastTokenUpdate?: Date;
}
/**
 * OAuth connection request interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthConnectionRequest {
    provider: OAuthPartnerId;
    purpose: OAuthPurpose;
    credentials: OAuthCredentials;
    profile?: BaseUserProfile;
}
/**
 * OAuth partner hook result interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthPartnerHookResult {
    partnerState: OAuthPartnerState;
    isConnecting: boolean;
    isConnected: boolean;
    error: Error | null;
    credentials: OAuthCredentials | null;
    connect: (options?: {
        purpose?: OAuthPurpose;
        redirectUri?: string;
        scopes?: string[];
        additionalParams?: Record<string, string>;
        onSuccess?: (result: OAuthPartnerResult) => void;
        onError?: (error: Error) => void;
    }) => Promise<void>;
    disconnect: () => Promise<boolean>;
    refreshToken: () => Promise<OAuthCredentials | null>;
    request: <T = any>(url: string, options?: OAuthApiRequestOptions) => Promise<T>;
}
/**
 * OAuth callback hook result interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthCallbackHookResult {
    isCallback: boolean;
    processing: boolean;
    result: OAuthResult | null;
    partnerName: string | null;
    success: boolean;
    error: Error | null;
}
/**
 * Exchange token request interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ExchangeTokenRequest {
    provider: OAuthPartnerId;
    purpose: OAuthPurpose;
    code: string;
    redirectUri: string;
    codeVerifier?: string;
    state?: string;
    instance?: string;
    idempotencyKey?: string;
}
/**
 * Token response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface TokenResponse {
    access_token: string;
    token_type?: string;
    expires_in?: number;
    refresh_token?: string;
    scope?: string;
    id_token?: string;
    created_at?: number;
}
/**
 * OAuth refresh request interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthRefreshRequest {
    provider: OAuthPartnerId;
    refreshToken: string;
    redirectUri: string;
}
/**
 * OAuth refresh response interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthRefreshResponse {
    access_token: string;
    token_type?: string;
    expires_in?: number;
    refresh_token?: string;
    scope?: string;
}

/**
 * GitHub repository configuration type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type GitHubRepoConfig = v.InferOutput<typeof githubRepoConfigSchema>;
/**
 * GitHub permission type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type GitHubPermission = v.InferOutput<typeof githubPermissionSchema>;
/**
 * Options for `useOAuth('connect')`.
 * Allows scope customization and extra auth URL parameters.
 *
 * @example
 * ```typescript
 * const connect = useOAuth('connect');
 * // Simple (defaults):
 * await connect('github');
 * // With scope override:
 * await connect('github', { purpose: 'api-access', scopes: ['repo', 'user:email'] });
 * ```
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */
interface ConnectOptions {
    /** OAuth purpose — defaults to 'api-access' */
    purpose?: OAuthPurpose;
    /** Override default scopes from schema. Only these scopes will be requested. */
    scopes?: string[];
    /** Extra query parameters to append to the auth URL */
    additionalParams?: Record<string, string>;
}
/**
 * Normalized response from server-side token exchange.
 * Callable providers (Firebase, Supabase) return this shape.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */
interface ExchangeTokenResponse {
    success: boolean;
    credentials: OAuthCredentials;
    profile?: BaseUserProfile;
}
/**
 * OAuth API type - complete interface for useOAuth hook
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthAPI {
    /**
     * Unified feature status - single source of truth for OAuth state.
     * Replaces deprecated `loading` boolean flag.
     * - `initializing`: OAuth is loading/initializing
     * - `ready`: OAuth fully operational
     * - `degraded`: OAuth unavailable (feature not installed/consent not given)
     * - `error`: OAuth encountered error
     */
    status: FeatureStatus;
    error: string | null;
    partners: Record<OAuthPartnerId, any>;
    connectedPartners: OAuthPartnerId[];
    connect: (partnerId: OAuthPartnerId, options?: ConnectOptions) => Promise<void>;
    disconnect: (partnerId: OAuthPartnerId) => Promise<void>;
    isConnected: (partnerId: OAuthPartnerId) => boolean;
    getCredentials: (partnerId: OAuthPartnerId) => OAuthCredentials | null;
    handleCallback: (partnerId: OAuthPartnerId, code: string, state?: string) => Promise<void>;
    isAvailable: boolean;
}

/**
 * @fileoverview Callable Provider Interface
 * @description Provider-agnostic interface for invoking server-side functions.
 * Firebase uses `httpsCallable`; Supabase uses `functions.invoke()`.
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */
/**
 * Provider-agnostic interface for calling server-side functions.
 *
 * @example
 * ```typescript
 * const callable: ICallableProvider = new SupabaseCallableProvider(client);
 * const result = await callable.call<{ userId: string }, { success: boolean }>(
 *   'delete-account',
 *   { userId: '123' }
 * );
 * ```
 *
 * @version 0.1.0
 * @since 0.5.0
 */
interface ICallableProvider {
    call<TReq, TRes>(functionName: string, data: TReq): Promise<TRes>;
}

/**
 * @fileoverview Storage Adapter Interface
 * @description Provider-agnostic interface for file/image storage.
 * Any storage backend (Firebase Storage, S3, Cloudflare R2, Supabase Storage) must implement this contract.
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */
/** Progress callback for upload operations (0-100) */
type UploadProgressCallback = (percent: number) => void;
/** Options for file upload */
interface UploadOptions {
    /** Folder path within the storage bucket (e.g. 'photos/2024'). Omit to upload to bucket root. */
    storagePath?: string;
    /** Custom filename override */
    filename?: string;
    /** Progress callback */
    onProgress?: UploadProgressCallback;
    /** AbortSignal to cancel the upload */
    signal?: AbortSignal;
}
/** Result of an upload operation */
interface UploadResult {
    /** Public URL of the uploaded file */
    url: string;
    /** Storage path of the uploaded file (for deletion) */
    path: string;
}
/**
 * Provider-agnostic storage adapter interface.
 *
 * Implementations:
 * - `FirebaseStorageAdapter` (Firebase Storage)
 * - Future: S3, Cloudflare R2, Supabase Storage adapters
 *
 * @version 0.1.0
 * @since 0.5.0
 */
interface IStorageAdapter {
    /** Upload a file or blob to storage. Returns the public URL and storage path. */
    upload(file: File | Blob, options?: UploadOptions): Promise<UploadResult>;
    /** Delete a file by its URL or storage path. */
    delete(urlOrPath: string, options?: {
        signal?: AbortSignal;
    }): Promise<void>;
    /** Get the public download URL for a storage path. */
    getUrl(path: string): Promise<string>;
}

/**
 * @fileoverview Provider Registry Types
 * @description Types for pluggable backends (CRUD, auth, storage, callable).
 * Consumers call `configureProviders()` once at app startup; `useCrud` and auth hooks
 * use these providers. Import `config/providers` from main.tsx before any CRUD usage.
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */

/**
 * All pluggable providers for the DoNotDev framework.
 *
 * - **crud** (required): CRUD adapter. Required for `useCrud` and entity operations.
 * - **auth** (optional): Client auth. Omit if using external auth.
 * - **storage** (optional): File/image storage. Omit if no uploads.
 * - **serverAuth** (optional): Server-side token verification.
 * - **callable** (optional): Server function invocation (e.g. Supabase Edge Functions).
 *
 * @example Firebase
 * ```typescript
 * configureProviders({
 *   crud: new FirestoreAdapter(),
 *   auth: new FirebaseAuth(),
 *   storage: new FirebaseStorageAdapter(),
 * });
 * ```
 *
 * @example Supabase
 * ```typescript
 * configureProviders({
 *   crud: new SupabaseCrudAdapter(supabase),
 *   auth: new SupabaseAuth(supabase),
 *   storage: new SupabaseStorageAdapter(supabase, 'your-bucket'),
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.5.0
 */
interface DndevProviders {
    /** Client-side authentication provider */
    auth?: AuthProvider;
    /** Server-side token verification and user management */
    serverAuth?: IServerAuthAdapter;
    /** Database / CRUD operations (required) */
    crud: ICrudAdapter;
    /** File and image storage */
    storage?: IStorageAdapter;
    /** Server-side function invocation (Edge Functions, Cloud Functions, API routes) */
    callable?: ICallableProvider;
}

/**
 * @fileoverview Network-Related Type Definitions
 * @description Centralized types for network connectivity, status tracking, and monitoring. Defines network connection types, network state, and network-related interfaces.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Possible network connection types based on the Network Information API
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type NetworkConnectionType = 'bluetooth' | 'cellular' | 'ethernet' | 'none' | 'wifi' | 'wimax' | 'other' | 'unknown';
/**
 * Effective connection speed types from the Network Information API
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type EffectiveConnectionType = 'slow-2g' | '2g' | '3g' | '4g' | 'unknown';
/**
 * Represents the network connectivity status.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface NetworkStatus {
    /**
     * Indicates whether the device has an active internet connection.
     * This is the primary status that authentication and other critical systems should check.
     */
    online: boolean;
    /**
     * The general type of the current network connection.
     * Based on the Network Information API.
     */
    connectionType: NetworkConnectionType;
    /**
     * The effective connection type based on measured performance.
     * Based on the Network Information API, might be 'unknown' if unavailable.
     */
    effectiveType?: EffectiveConnectionType | string;
    /** The timestamp when the network status was last checked or updated. */
    lastChecked: Date;
}
/**
 * Network state specifically for store usage
 * Variant of NetworkStatus with string timestamp for serialization
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface NetworkState {
    /** Whether the device is currently online */
    online: boolean;
    /**
     * Type of network connection if available
     * Uses the full range of network connection types from the Network Information API
     */
    connectionType: NetworkConnectionType;
    /**
     * The effective connection type based on measured performance.
     * Based on the Network Information API, might be 'unknown' if unavailable.
     */
    effectiveType?: EffectiveConnectionType | string;
    /** ISO date string of when network status was last checked */
    lastChecked: string;
}
/**
 * Configuration options for the NetworkManager.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface NetworkCheckConfig {
    /**
     * URL to ping (using a HEAD request) to verify actual internet connectivity.
     * Defaults to a reliable Google endpoint. Set to null or empty string to disable pinging.
     * @default "https://www.gstatic.com/generate_204"
     */
    pingEndpoint?: string | null;
    /**
     * Timeout in milliseconds for the ping request.
     * @default 5000
     */
    pingTimeout?: number;
    /**
     * Interval in milliseconds for periodically checking network connectivity via ping.
     * @default 30000 (30 seconds)
     */
    checkInterval?: number;
    /**
     * Debounce time in milliseconds for processing browser online/offline events
     * to avoid rapid status fluctuations.
     * @default 300
     */
    debounceTime?: number;
}
/**
 * Function signature for network reconnection callbacks
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type NetworkReconnectCallback = () => void;
/**
 * Generic observable interface to avoid circular dependencies
 * This allows us to define the interface without depending on Subject implementation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface Observable<T> {
    subscribe: (next: (value: T) => void, error?: (error: any) => void, complete?: () => void) => {
        unsubscribe: () => void;
    };
}
/**
 * Network manager interface for observing and controlling network status
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface INetworkManager {
    /** Get the current network status */
    getStatus(): NetworkStatus;
    /**
     * Observe network status changes
     * @returns An observable of NetworkStatus updates
     */
    observeStatus(): Observable<NetworkStatus>;
    /**
     * Register a callback for reconnection events
     * @param callback Function to execute when network reconnects
     * @returns Unsubscribe function
     */
    onReconnect(callback: NetworkReconnectCallback): () => void;
    /**
     * Manually check connectivity
     * @param url Optional custom URL to check
     * @returns Promise resolving to true if online, false otherwise
     */
    checkConnectivity(url?: string): Promise<boolean>;
    /** Clean up resources */
    destroy(): void;
}

/**
 * @fileoverview Rate Limiter Types
 * @description Type definitions for rate limiting. Defines rate limit configuration, rate limit state, rate limit result, and rate limiting-related interfaces.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Configuration options for rate limiting
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RateLimitConfig {
    /** Maximum number of allowed attempts within the window */
    maxAttempts: number;
    /** Time window in milliseconds */
    windowMs: number;
    /** Duration to block after maxAttempts is reached (ms) */
    blockDurationMs: number;
    /**
     * Whether to increase block duration exponentially for repeated blocks
     * @default true
     */
    useExponentialBackoff?: boolean;
    /**
     * Key for storage - should be unique per application or feature
     * @default "dndev_auth_ratelimit"
     */
    storageKey: string;
    /**
     * Maximum block duration in milliseconds
     * @default 86400000 (24 hours)
     */
    maxBlockDurationMs?: number;
}
/**
 * Result of a rate limit check
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RateLimitResult {
    /** Whether the operation is allowed */
    allowed: boolean;
    /** Number of attempts remaining before being rate limited */
    remaining: number;
    /** When the rate limit window or block will reset */
    resetAt: Date | null;
    /** Seconds remaining in block (null if not blocked) */
    blockRemainingSeconds: number | null;
}
/**
 * Internal structure used by RateLimiter to store attempt timestamps and block info.
 * @private
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AttemptRecord {
    /** Array of attempts with timestamps and optional identifiers */
    attempts: Array<{
        /** When the attempt was made */
        timestamp: number;
        /** Optional identifier (e.g., email, username) */
        identifier?: string;
    }>;
    /** Timestamp when the block expires, or null if not blocked */
    blockUntil: number | null;
    /** Number of consecutive times blocking occurred (for exponential backoff) */
    blockCount: number;
}
/**
 * Rate limiter interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RateLimiter {
    /**
     * Check if an operation is allowed and record an attempt
     * @param identifier Optional identifier (e.g. email, username)
     * @returns Rate limit result
     */
    consume(identifier?: string): RateLimitResult;
    /**
     * Check rate limit without recording an attempt
     * @param identifier Optional identifier
     * @returns Rate limit result
     */
    check(identifier?: string): RateLimitResult;
    /**
     * Reset rate limiting state
     */
    reset(): void;
    /**
     * Reset rate limiting for a specific identifier
     * @param identifier The identifier to reset
     */
    resetForIdentifier(identifier: string): void;
}
/**
 * Rate limiting state for a specific operation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RateLimitState {
    /** Number of attempts made in the current window */
    attempts: number;
    /** ISO date string when the current rate limit window started */
    windowStart: string;
    /** ISO date string when the block expires, or null if not blocked */
    blockUntil: string | null;
}
/**
 * Rate limit manager interface for application-wide use
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RateLimitManager {
    /**
     * Get a rate limiter for a specific operation
     * @param operation Operation to rate limit
     * @param config Optional configuration overrides
     */
    getLimiter(operation: string, config?: Partial<RateLimitConfig>): RateLimiter;
    /**
     * Reset all rate limiters
     */
    resetAll(): void;
}

/**
 * @fileoverview Store Types
 * @description Type definitions for store system. Defines store API types, state types, and store-related interfaces for managing application state.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * DoNotDev store API interface without direct Zustand dependency.
 * Renamed from StoreApi to avoid shadowing Zustand's StoreApi.
 * @template T - The store state type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface DndevStoreApi<T> {
    /** Returns the current state */
    getState: () => T;
    /** Updates the store state */
    setState: (partial: Partial<T> | ((state: T) => Partial<T>), replace?: boolean) => void;
    /** Subscribes to state changes */
    subscribe: (listener: (state: T, prevState: T) => void) => () => void;
}
/**
 * Base store state that all stores should implement
 * Provides common properties for loading, error handling, and readiness
 *
 * **Lifecycle Timeline:**
 * 1. Store created → `isReady: false`, `isDataResolved: false`
 * 2. Service init complete → `isReady: true`, `isDataResolved: false`
 * 3. First async callback → `isReady: true`, `isDataResolved: true`
 *
 * @property isReady - Service is initialized and methods can be called
 * @property isDataResolved - First async data callback has fired (user/data resolved)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseStoreState {
    /** Whether the store is ready to be used by components */
    isReady: boolean;
    /** Whether the store is currently loading */
    isLoading: boolean;
    /** Current error message, or null if no error */
    error: string | null;
    /**
     * Whether Zustand persist middleware has finished rehydrating from storage.
     * Only present on stores created with persistOptions.
     * `false` before rehydration, `true` after. Non-persisted stores: undefined.
     */
    _hasHydrated?: boolean;
    /**
     * Whether the first async data callback has fired.
     * Optional - only needed for stores with async data sources (e.g., auth, realtime).
     *
     * For AuthStore: equivalent to `authStateChecked` (first onAuthStateChanged)
     * For other stores: set when initial data load completes
     */
    isDataResolved?: boolean;
}
/**
 * Base store actions that all stores should implement
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseStoreActions {
    /** Set the store readiness state */
    setReady: (ready: boolean) => void;
    /** Set the loading state */
    setLoading: (loading: boolean) => void;
    /** Set the error state */
    setError: (error: string | null) => void;
    /** Clear the current error */
    clearError: () => void;
    /** Reset the store to initial state */
    reset: () => void;
    /**
     * Set the data resolved state (optional).
     * Only implement for stores with async data sources.
     *
     * For AuthStore: call when first onAuthStateChanged fires
     * For other stores: call when initial data load completes
     */
    setDataResolved?: (resolved: boolean) => void;
}
/**
 * Base UI state for an entity.
 * @template T - The entity type.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseState<T> extends BaseStoreState {
    /** Currently selected item */
    selected?: T;
    /** Active filters */
    filters: Record<string, any>;
    /** Current sort configuration */
    sort?: {
        field: keyof T;
        direction: 'asc' | 'desc';
    };
}
/**
 * Base actions for UI state management.
 * @template T - The entity type.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface BaseActions<T> extends BaseStoreActions {
    /** Select or deselect an item */
    select: (item?: T) => void;
    /** Update active filters */
    setFilters: (filters: Record<string, any>) => void;
    /** Set the sorting configuration */
    setSort: (field: keyof T, direction: 'asc' | 'desc') => void;
}
/**
 * Combined store type including state and actions.
 * @template T - The entity type.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type Store<T> = BaseState<T> & BaseActions<T>;
/**
 * Authentication token state
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface TokenState {
    /** The authentication token string or null if not authenticated */
    token: string | null;
    /** ISO date string of when the token expires */
    expiresAt: string | null;
    /** Current status of the token */
    status: TokenStatus;
}
/**
 * OAuth store state
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthStoreState {
    connections: Record<OAuthPartnerId, OAuthPartnerState>;
    loading: boolean;
    error: Error | null;
}
/**
 * Simple auth state store interface - only state, no mechanisms
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface AuthStateStore {
    authenticated: boolean;
    userId: string | null;
    user: AuthUser | null;
    role: UserRole;
    token: {
        token: string | null;
        expiresAt: Date | null;
        status: TokenStatus;
    };
    network: {
        online: boolean;
        connectionType: NetworkConnectionType;
        lastChecked: string;
    };
    rateLimit: Record<string, RateLimitState>;
    error: string | null;
    errorCode: string | undefined;
    loading: boolean;
    initialized: boolean;
    subscription: {
        tier: string;
        isActive: boolean;
        expiresAt: Date | null;
        features: string[];
        daysRemaining: number | null;
    };
    setAuthenticated: (authenticated: boolean, userId?: string | null) => void;
    setUser: (user: AuthUser | null) => void;
    setRole: (role: UserRole) => void;
    setToken: (token: string | null, expiresAt?: Date | null) => void;
    updateTokenStatus: (status: TokenStatus) => void;
    setNetworkStatus: (online: boolean, connectionType?: NetworkConnectionType) => void;
    setError: (error: string | null, errorCode?: string) => void;
    setLoading: (loading: boolean) => void;
    setSubscription: (subscription: {
        tier: string;
        isActive: boolean;
        expiresAt: Date | null;
        features: string[];
        daysRemaining: number | null;
    }) => void;
    setInitialized: (initialized: boolean) => void;
    clearError: () => void;
    reset: () => void;
}
/**
 * OAuth store actions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface OAuthStoreActions {
    setLoading: (loading: boolean) => void;
    setGlobalError: (error: Error | null) => void;
    reset: () => void;
    isConnected: (partnerId: OAuthPartnerId, purpose?: OAuthPurpose) => boolean;
    getCredentials: (partnerId: OAuthPartnerId) => OAuthCredentials | null;
}

/**
 * @fileoverview UI Types
 * @description Type definitions for UI system. Defines UI-related interfaces and form field types.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Theme information structure with enhanced metadata
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ThemeInfo {
    /** Unique theme identifier */
    name: string;
    /** User-friendly display name */
    displayName: string;
    /** Theme description */
    description?: string;
    /** Whether this is a dark theme */
    isDark: boolean;
    /** CSS variables for this theme */
    variables?: Record<string, string>;
    /** Enhanced theme metadata */
    meta: {
        /** Icon identifier for UI (e.g., 'SunIcon', 'MoonIcon') */
        icon: string;
        /** Optional theme description for UI */
        description?: string;
        /** Optional category for grouping themes */
        category?: string;
        /** Optional author information */
        author?: string;
        /** Additional metadata */
        [key: string]: any;
    };
}
/**
 * Theme mode setting
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ThemeMode = 'light' | 'dark' | 'auto';
/**
 * Theme state in the store
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ThemeState {
    /** Currently active theme */
    currentTheme: string;
    /** List of available themes */
    availableThemes: ThemeInfo[];
    /** Whether dark mode is currently active */
    isDarkMode: boolean;
    /** User's theme mode preference */
    themeMode: ThemeMode;
    /** Loading state for theme operations */
    isLoading: boolean;
    /** Error state for theme operations */
    error: string | null;
}
/**
 * Enhanced theme actions for the store
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ThemeActions {
    /** Set the current theme with DOM application and persistence */
    setTheme: (theme: string) => Promise<void>;
    /** Update the list of available themes */
    setAvailableThemes: (themes: ThemeInfo[]) => void;
    /** Set dark mode state */
    setDarkMode: (isDark: boolean) => void;
    /** Set theme mode preference */
    setThemeMode: (mode: ThemeMode) => void;
    /** Set loading state */
    setLoading: (isLoading: boolean) => void;
    /** Set error state */
    setError: (error: string | null) => void;
    /** Clear error */
    clearError: () => void;
    /** Check if a theme is available */
    isThemeAvailable: (themeName: string) => boolean;
    /** Reset theme settings to defaults */
    resetTheme: () => void;
    /** Get theme info for the current theme */
    getCurrentThemeInfo: () => ThemeInfo | null;
    /** Switch to the next available theme */
    switchToNextTheme: () => void;
    /** Toggle between light and dark theme variants */
    toggleDarkMode: () => void;
    /**
     * Initialize theme system with discovery data and user config
     * @param appConfig - Full AppConfig from AppConfigProvider (store extracts what it needs)
     */
    initialize: (appConfig?: AppConfig) => Promise<boolean>;
}
/**
 * Modal state and actions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ModalState {
    /** Whether the modal is currently open */
    isOpen: boolean;
    /** Modal content */
    content: ReactNode | null;
}
/**
 * Modal actions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ModalActions {
    /** Open the modal with content */
    openModal: (content: ReactNode) => void;
    /** Close the modal */
    closeModal: () => void;
}
/**
 * Phase of the redirect overlay progression
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type RedirectOverlayPhase = 'connecting' | 'preparing' | 'redirecting' | 'timeout';
/**
 * Billing-specific redirect operations
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type BillingRedirectOperation = 'stripe-checkout' | 'stripe-portal';
/**
 * Auth partner redirect operations - DRY derived from AUTH_PARTNERS schema
 * Format: `oauth-${partnerId}` for OAuth partners, `auth-${partnerId}` for auth-only
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AuthRedirectOperation = `oauth-${AuthPartnerId}` | `auth-${AuthPartnerId}`;
/**
 * OAuth partner redirect operations - DRY derived from OAUTH_PARTNERS schema
 * Format: `oauth-api-${partnerId}` for API-only OAuth partners
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type OAuthRedirectOperation = `oauth-api-${OAuthPartnerId}`;
/**
 * All redirect operations - Union of billing, auth, and OAuth operations
 * Extensible via string intersection for custom operations
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type RedirectOperation = BillingRedirectOperation | AuthRedirectOperation | OAuthRedirectOperation | (string & {});
/**
 * Configuration for redirect overlay (optional overrides)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RedirectOverlayConfig {
    /** i18n namespace to use (default: inferred from operation) */
    namespace?: string;
    /** Custom title (overrides i18n) */
    title?: string;
    /** Custom message (overrides i18n) */
    message?: string;
    /** Custom subtitle (overrides i18n) */
    subtitle?: string;
    /** Icon type: 'lock' for payments, 'shield' for auth (default: inferred) */
    icon?: 'lock' | 'shield' | 'none';
    /** Timeout in ms before showing cancel button (default: 10000) */
    cancelTimeout?: number;
}
/**
 * Redirect overlay state
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RedirectOverlayState {
    /** Whether the redirect overlay is visible */
    isRedirectOverlayOpen: boolean;
    /** Current operation being performed */
    redirectOperation: RedirectOperation | null;
    /** Current phase of the redirect */
    redirectPhase: RedirectOverlayPhase;
    /** Whether cancel button should be shown */
    showCancelButton: boolean;
    /** Configuration overrides */
    redirectConfig: RedirectOverlayConfig | null;
    /** Timestamp when overlay was shown (for phase progression) */
    redirectStartTime: number | null;
}
/**
 * Redirect overlay actions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface RedirectOverlayActions {
    /** Show the redirect overlay */
    showRedirectOverlay: (operation: RedirectOperation, config?: RedirectOverlayConfig) => void;
    /** Hide the redirect overlay */
    hideRedirectOverlay: () => void;
    /** Update the current phase (internal use) */
    setRedirectPhase: (phase: RedirectOverlayPhase) => void;
    /** Show/hide cancel button (internal use) */
    setShowCancelButton: (show: boolean) => void;
}
/**
 * Loading state
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface LoadingState {
    /** Whether a data fetch operation is in progress */
    isLoading: boolean;
    /** Whether a background fetch operation is in progress */
    isFetching: boolean;
}
/**
 * Loading actions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface LoadingActions {
    /** Set the loading state */
    setLoading: (isLoading: boolean) => void;
    /** Set the fetching state */
    setFetching: (isFetching: boolean) => void;
}
/**
 * Cookie options for setting cookies
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface CookieOptions {
    /** Cookie expiration in days (default: 365) */
    expires?: number;
    /** Cookie path (default: '/') */
    path?: string;
    /** Cookie domain */
    domain?: string;
    /** Secure flag (default: true) */
    secure?: boolean;
    /** SameSite attribute (default: 'strict') */
    sameSite?: 'strict' | 'lax' | 'none';
    /** Cookie priority (Chrome 99+) */
    priority?: 'low' | 'medium' | 'high';
    /** Partitioned flag (Chrome 114+) */
    partitioned?: boolean;
}
/**
 * Consent category constants - DRY single source of truth
 * Use these instead of hardcoded strings throughout the codebase
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const CONSENT_CATEGORY: {
    readonly NECESSARY: "necessary";
    readonly FUNCTIONAL: "functional";
    readonly ANALYTICS: "analytics";
    readonly MARKETING: "marketing";
};
/**
 * Consent category type - auto-derived from constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ConsentCategory = (typeof CONSENT_CATEGORY)[keyof typeof CONSENT_CATEGORY];
/**
 * Density constants - DRY single source of truth
 * Used for spacing and typography presets via data-density attribute
 * CSS uses these string values directly, but TypeScript code should use constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const DENSITY: {
    readonly COMPACT: "compact";
    readonly STANDARD: "standard";
    readonly EXPRESSIVE: "expressive";
};
/**
 * Density type - auto-derived from constants
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type Density = (typeof DENSITY)[keyof typeof DENSITY];
/**
 * Cookie consent categories
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface DoNotDevCookieCategories {
    /** Always granted, cannot be declined - core functionality */
    necessary: boolean;
    /** Requires consent - Firebase Auth, user preferences */
    functional: boolean;
    /** Requires consent - analytics, performance monitoring */
    analytics: boolean;
    /** Requires consent - marketing, ads, remarketing */
    marketing: boolean;
}
/**
 * App cookie categories type
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type AppCookieCategories = Partial<DoNotDevCookieCategories> & {
    necessary: boolean;
};
/**
 * Consent state interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ConsentState {
    /** Whether user has made a consent choice */
    hasConsented: boolean;
    /** Individual category permissions - only includes categories that are actually required */
    categories: AppCookieCategories;
    /** When consent was last updated */
    timestamp: string | null;
    /** Consent version for future migrations */
    version: string;
}
/**
 * Consent actions interface
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ConsentActions {
    /** Accept all optional categories */
    acceptAll: () => void;
    /** Decline all optional categories */
    declineAll: () => void;
    /** Update specific category */
    updateCategory: (category: keyof DoNotDevCookieCategories, value: boolean) => void;
    /** Check if category is granted */
    hasCategory: (category: keyof DoNotDevCookieCategories) => boolean;
    /** Reset consent (for testing) */
    reset: () => void;
    /** Save consent to cookie */
    saveConsent: () => void;
    /** Show cookie banner (for cookie settings link) */
    showCookieBanner: () => void;
}
/**
 * Consent API - All available properties and methods from consent store
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ConsentAPI extends ConsentState, ConsentActions {
    /** Whether banner should be shown */
    showBanner: boolean;
}
/**
 * Feature/Consent Matrix
 *
 * Single source of truth for:
 * - Which features exist in the framework
 * - What consent each feature requires
 * - Type-safe feature names across codebase
 *
 * Uses CONSENT_CATEGORY constants for DRY compliance
 *
 * @example
 * ```typescript
 * // SaaS app (Auth + Billing)
 * features: ['auth', 'billing'] // No consent required (both necessary)
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const FEATURE_CONSENT_MATRIX: {
    /** Authentication - Firebase Auth, user sessions */
    readonly auth: {
        readonly requiresConsent: null;
    };
    /** OAuth - Third-party authentication (Google, GitHub, etc.) */
    readonly oauth: {
        readonly requiresConsent: null;
    };
    /** Billing - Stripe subscriptions, payments */
    readonly billing: {
        readonly requiresConsent: null;
    };
    /** Analytics - Usage tracking, performance monitoring */
    readonly analytics: {
        readonly requiresConsent: "analytics";
    };
    /** Marketing - Advertising, retargeting */
    readonly marketing: {
        readonly requiresConsent: "marketing";
    };
};
/**
 * Feature name type - auto-derived from matrix
 * TypeScript ensures only valid features are used
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FeatureName = keyof typeof FEATURE_CONSENT_MATRIX;
/**
 * Get consent requirement for a specific feature
 *
 * @example
 * ```typescript
 * type AuthConsent = FeatureConsentRequirement<'auth'>; // 'functional'
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FeatureConsentRequirement<F extends FeatureName> = (typeof FEATURE_CONSENT_MATRIX)[F]['requiresConsent'];
/**
 * Get all features requiring a specific consent category
 *
 * @example
 * ```typescript
 * type FunctionalFeatures = FeaturesRequiringConsent<'functional'>;
 * // 'auth' | 'oauth' | 'billing'
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FeaturesRequiringConsent<C extends keyof DoNotDevCookieCategories> = {
    [K in FeatureName]: FeatureConsentRequirement<K> extends C ? K : never;
}[FeatureName];
/**
 * Features that require any consent (excludes null)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FeaturesRequiringAnyConsent = {
    [K in FeatureName]: FeatureConsentRequirement<K> extends null ? never : K;
}[FeatureName];
/**
 * Features that don't require consent
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type FeaturesWithoutConsent = {
    [K in FeatureName]: FeatureConsentRequirement<K> extends null ? K : never;
}[FeatureName];

/**
 * @fileoverview Canvas catalog types
 * @description TypeScript-only types describing widget definitions and the
 *   shape stored in the catalog registry. Runtime validation lives in
 *   `@donotdev/schemas` (see `schemas/common/canvas.ts`). This file is
 *   purely structural and isomorphic (no React imports).
 *
 * The React component side of the registered widget is a concern of
 * `@donotdev/canvas` (the UI package). Server-side consumers (validators,
 * brokers) only need the definition shape, not the rendered component.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */

/**
 * Which surface a widget is allowed to render on.
 *
 * - `household` — any authenticated member.
 * - `private` — member-scoped (mail, 2nd-brain, homework).
 * - `meta` — framing widgets (TextBlock, Composite, ProgressCanvas, Confirmation).
 */
type CanvasSurface = 'household' | 'private' | 'meta';
/**
 * A valibot schema with an inferable output type. Accepts the generic base
 * schema shape used across the monorepo without locking to a specific issue type.
 */
type AnyValibotSchema = v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>;
/**
 * Declarative widget definition — the static metadata a widget module
 * exports before it is paired with its React component for registration.
 *
 * Discriminator: `kind` (string literal, unique in the catalog).
 *
 * - `schema` validates the block `payload` for this kind.
 * - `actions` is a record of action-name -> schema validating that action's event payload.
 * - `surface` controls policy-layer gating.
 * - `defaultLifetime` is used by the agent-side emitter when the agent does not override it.
 */
interface WidgetDef<Kind extends string = string, PayloadSchema extends AnyValibotSchema = AnyValibotSchema, Actions extends Record<string, AnyValibotSchema> = Record<string, AnyValibotSchema>> {
    readonly kind: Kind;
    readonly schema: PayloadSchema;
    readonly actions: Actions;
    readonly surface: CanvasSurface;
    readonly defaultLifetime?: CanvasLifetime;
}
/**
 * Canvas block lifetime. Kept as a type alias here — the runtime schema
 * `CanvasLifetimeSchema` lives in `@donotdev/schemas`.
 *
 * - `ephemeral` — vanishes with the current turn (default).
 * - `session` — pinned to the current chat thread.
 * - `persistent` — lives on the PWA dashboard until manually removed.
 */
type CanvasLifetime = 'ephemeral' | 'session' | 'persistent';
/**
 * Optional display hints attached to a canvas block.
 */
interface CanvasWidgetMetadata {
    readonly title?: string;
    readonly pinnable?: boolean;
    readonly preferredHeight?: number;
}
/**
 * Envelope for a single canvas block emitted by the agent.
 *
 * `payload` is intentionally `unknown` at the envelope level — it is
 * validated against the registered widget's payload schema inside
 * `validateBlock`. Do not trust `payload` without that check.
 */
interface CanvasBlock {
    readonly id: string;
    readonly kind: string;
    readonly lifetime: CanvasLifetime;
    readonly metadata?: CanvasWidgetMetadata;
    readonly payload: unknown;
}
/**
 * Envelope for a user interaction event emitted back to the agent.
 *
 * `payload` is validated against the widget's per-action schema inside
 * `validateEvent`.
 */
interface CanvasEvent {
    readonly widgetId: string;
    readonly action: string;
    readonly payload: unknown;
}
/**
 * Caller access tier passed to `validateBlock` for surface gating.
 *
 * Mirrors the gontrand access model. `kid` and `null` fail closed for any
 * non-`meta` surface at the canvas boundary.
 */
type CanvasCallerAccess = 'admin' | 'member' | 'kid' | null;
/**
 * Optional options for `validateBlock`. When `caller` is present, the
 * widget's `surface` is matched against the caller's access tier after
 * envelope / kind / payload checks pass.
 */
interface ValidateBlockOptions {
    readonly caller?: {
        readonly access: CanvasCallerAccess;
    };
}
/**
 * Props every widget component receives from `CanvasHost`. The React
 * component shape itself lives in `@donotdev/canvas` (UI package).
 */
interface CanvasWidgetProps {
    readonly payload: unknown;
    readonly emit: (action: string, payload: unknown) => void;
}

/** Options for the handleError utility. */
interface HandleErrorOptions {
    userMessage?: string;
    context?: Record<string, any>;
    log?: boolean;
    reportToSentry?: boolean;
    showNotification?: boolean;
    severity?: 'error' | 'warning' | 'info' | 'success';
    notificationTimeout?: number;
}
/**
 * Universal error handler for DoNotDev applications
 *
 * Handles errors from any source, converting them to standardized DoNotDevError
 * objects, logging appropriately, and optionally adding to UI notification system.
 *
 * @param error - The original error from any source
 * @param optionsOrMessage - Optional configuration or user-friendly message
 * @returns Standardized DoNotDevError
 *
 * @example
 * try {
 *   await fetchData();
 * } catch (error) {
 *   throw handleError(error, 'Failed to fetch data');
 * }
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function handleError(error: unknown, optionsOrMessage?: HandleErrorOptions | string): DoNotDevError;
/**
 * Creates a wrapped function that handles errors automatically
 *
 * @param fn - Function to wrap with error handling
 * @param options - Error handling options or user message
 * @returns Wrapped function with error handling
 *
 * @example
 * const safeFetchData = withErrorHandling(fetchData, 'Failed to fetch data');
 * await safeFetchData();
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function withErrorHandling<T extends (...args: any[]) => any>(fn: T, options?: HandleErrorOptions | string): (...args: Parameters<T>) => Promise<ReturnType<T>>;
/**
 * Display a notification message (client-only)
 * This is a stub - actual implementation should be in client-side code
 * that imports toast directly from @donotdev/components
 *
 * @param message Message to display
 * @param severity Severity level
 * @param timeout Optional timeout in milliseconds
 * @returns ID of the notification
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function showNotification(message: string, severity?: 'error' | 'warning' | 'info' | 'success', timeout?: number): string;

/**
 * @fileoverview Error source detection module
 * @description Automatically detects the source of errors to apply appropriate handling
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Detects the source of an error based on its properties and structure
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param error - The error to analyze
 * @returns The detected error source
 */
declare function detectErrorSource(error: unknown): ErrorSource;

/**
 * Default error messages for standard error codes
 * These provide a fallback when no specific message is available
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const DEFAULT_ERROR_MESSAGES: Record<ErrorCode, string>;
/**
 * Maps an error from any source to a standardized DoNotDevError
 *
 * This is the central error mapping function that routes errors to the appropriate
 * handler based on the detected source.
 *
 * @param error - The original error
 * @param source - The detected error source
 * @param userMessage - Optional user-friendly message
 * @returns A standardized DoNotDevError
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function mapToDoNotDevError(error: unknown, source: ErrorSource, userMessage?: string): DoNotDevError;

/**
 * @fileoverview Sentry integration module
 * @description Handles capturing errors to Sentry with appropriate context.
 * Works universally on both client and server - uses globalThis.Sentry which
 * is set by both @sentry/react and @sentry/node when initialized.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Captures an error to Sentry with additional context
 * Works on both client (@sentry/react) and server (@sentry/node)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param error - The error to capture
 * @param source - The detected error source
 * @param context - Additional context to include
 */
declare function captureErrorToSentry(error: DoNotDevError, source: ErrorSource, context?: Record<string, any>): void;

/**
 * @fileoverview Standard error handling factory
 * @description Creates error handlers that map any source error to DoNotDevError format
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Type for error handler functions
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
type ErrorHandlerFunction = (error: unknown, userMessage?: string) => DoNotDevError;
/**
 * Core configuration for error handlers
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
interface ErrorHandlerConfig {
    errorSource: ErrorSource;
    defaultErrorCode: ErrorCode;
    defaultErrorMessage: string;
    errorCodeMapping?: Record<string, ErrorCode>;
    friendlyMessageMapping?: Record<string, string>;
    extractErrorCode?: (error: unknown) => string | undefined;
    extractErrorMessage?: (error: unknown) => string | undefined;
    processMetadata?: (error: unknown) => Record<string, any>;
}
/**
 * Creates an error handler that converts any type of error to DoNotDevError format
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param config Configuration for the error handler
 * @returns A function that converts errors to DoNotDevErrors
 */
declare function createErrorHandler(config: ErrorHandlerConfig): ErrorHandlerFunction;
/**
 * Common error code mappings for most services
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare const commonErrorCodeMappings: Record<string, ErrorCode>;

/**
 * @fileoverview Adapter Error Utilities
 * @description Utility functions for wrapping errors in adapter implementations.
 * These utilities help maintain consistent error handling across all adapters without
 * requiring inheritance or base classes.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Wraps an error from a CRUD adapter operation.
 * Maps common database/API errors to DoNotDevError with appropriate codes.
 *
 * @param error - The original error from the adapter
 * @param context - Context about the operation (e.g., "FirestoreAdapter.get", "SupabaseAdapter.add")
 * @param operation - The operation name (e.g., "get", "add", "query")
 * @param collection - The collection/table name
 * @param id - Optional document ID
 * @returns A DoNotDevError wrapping the original error
 *
 * @example
 * ```typescript
 * try {
 *   return await this.client.from('users').select().eq('id', id).single();
 * } catch (error) {
 *   throw wrapCrudError(error, 'SupabaseCrudAdapter.get', 'get', 'users', id);
 * }
 * ```
 */
declare function wrapCrudError(error: unknown, context: string, operation: string, collection: string, id?: string): DoNotDevError;
/**
 * Wraps an error from a storage adapter operation.
 *
 * @param error - The original error from the adapter
 * @param context - Context about the operation (e.g., "FirebaseStorageAdapter.upload")
 * @param operation - The operation name (e.g., "upload", "delete", "getUrl")
 * @param path - The storage path or URL
 * @returns A DoNotDevError wrapping the original error
 *
 * @example
 * ```typescript
 * try {
 *   return await this.bucket.upload(file, { destination: path });
 * } catch (error) {
 *   throw wrapStorageError(error, 'S3StorageAdapter.upload', 'upload', path);
 * }
 * ```
 */
declare function wrapStorageError(error: unknown, context: string, operation: string, path: string): DoNotDevError;
/**
 * Wraps an error from an auth adapter operation.
 *
 * @param error - The original error from the adapter
 * @param context - Context about the operation (e.g., "FirebaseAuth.signInWithEmail")
 * @param operation - The operation name (e.g., "signInWithEmail", "linkWithPartner")
 * @param details - Optional additional details (e.g., email, partnerId)
 * @returns A DoNotDevError wrapping the original error
 *
 * @example
 * ```typescript
 * try {
 *   return await this.sdk.signInWithEmailAndPassword(email, password);
 * } catch (error) {
 *   throw wrapAuthError(error, 'CustomAuth.signInWithEmail', 'signInWithEmail', { email });
 * }
 * ```
 */
declare function wrapAuthError(error: unknown, context: string, operation: string, details?: Record<string, unknown>): DoNotDevError;

/**
 * Validates data against a schema, throwing a DoNotDevError if validation fails.
 * Use this in adapter methods to ensure data conforms to expected schemas.
 *
 * @param schema - The Valibot schema to validate against
 * @param data - The data to validate
 * @param context - Context for error messages (e.g., "FirestoreAdapter.add")
 * @returns The validated and parsed data
 * @throws DoNotDevError if validation fails
 *
 * @example
 * ```typescript
 * async add<T>(collection: string, data: T, schema?: dndevSchema<T>): Promise<{ id: string; data: Record<string, unknown> }> {
 *   if (schema) {
 *     data = validateWithSchema(schema, data, 'MyAdapter.add');
 *   }
 *   // ... proceed with validated data
 * }
 * ```
 */
declare function validateWithSchema<T>(schema: dndevSchema<T>, data: unknown, context: string): T;
/**
 * Safely validates data against a schema, returning null if validation fails instead of throwing.
 * Useful when you want to handle validation errors gracefully.
 *
 * @param schema - The Valibot schema to validate against
 * @param data - The data to validate
 * @returns The validated data, or null if validation fails
 *
 * @example
 * ```typescript
 * const validated = safeValidate(schema, rawData);
 * if (!validated) {
 *   console.warn('Data validation failed, skipping...');
 *   return null;
 * }
 * ```
 */
declare function safeValidate<T>(schema: dndevSchema<T>, data: unknown): T | null;
/**
 * Creates a spreadable object from validated data, ensuring it can be safely spread.
 * Use this when you need to spread validated data and add additional properties (like `id`).
 *
 * @param data - The validated data (should be an object)
 * @returns A Record that can be safely spread
 *
 * @example
 * ```typescript
 * const parsed = validateWithSchema(schema, data, 'MyAdapter.get');
 * return { ...ensureSpreadable(parsed), id } as T;
 * ```
 */
declare function ensureSpreadable<T>(data: T): Record<string, unknown>;

/**
 * @fileoverview Array translation utilities
 * @description Provides utilities for handling array translations with indexed keys
 *
 * This module provides utilities to simplify the common pattern of accessing
 * array translations using indexed keys instead of returnObjects.
 *
 * **Why This Pattern?**
 * - Performance: Indexed access is faster than object parsing
 * - Consistency: Matches the framework's established patterns
 * - Reliability: Works across all i18n modes (standalone, UI, EDA)
 * - Filtering: Easy to filter out missing translations (returns key when missing)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 *
 * **Usage Pattern:**
 * ```typescript
 * import { translateArray } from '@donotdev/utils';
 *
 * const benefits = translateArray(t, 'benefits', 6); // Gets benefits.0 through benefits.5
 * const features = translateArray(t, 'features.list', 3); // Gets features.list.0 through features.list.2
 * ```
 */
/**
 * Translates an array using indexed keys and filters out missing translations
 *
 * **IMPORTANT:** This works with JSON arrays directly. i18next automatically treats
 * array indices as object keys, so `t('items.0')` works when JSON has `"items": ["value1", ...]`
 *
 * @param t - Translation function from useTranslation hook
 * @param keyPrefix - Base key prefix for the array (e.g., 'benefits', 'features.list')
 * @param maxIndex - Maximum index to check (exclusive, so 6 means indices 0-5)
 * @param options - Additional options for filtering
 * @returns Array of translated strings with missing translations filtered out
 *
 * @example
 * // JSON: { "benefits": ["value1", "value2", "value3"] }
 * const benefits = translateArray(t, 'benefits', 6);
 * // Result: ["value1", "value2", "value3"]
 * // Works because i18next treats arrays as objects with numeric keys
 *
 * @example
 * // JSON: { "features": { "list": ["feature1", "feature2"] } }
 * const features = translateArray(t, 'features.list', 5);
 * // Result: ["feature1", "feature2"]
 *
 * @example
 * // JSON: { "items": ["a", "b", "c", "d"] }
 * // Usage with List component:
 * <List items={translateArray(t, 'items', 10)} />
 * // i18next accesses items.0, items.1, etc. automatically
 *
 * @example
 * // With custom filtering
 * const items = translateArray(t, 'items', 10, {
 *   minLength: 2, // Only include items with at least 2 characters
 *   excludeEmpty: true // Exclude empty strings
 * });
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function translateArray(t: TFunction, keyPrefix: string, maxIndex: number, options?: {
    minLength?: number;
    excludeEmpty?: boolean;
    customFilter?: (item: string, index: number) => boolean;
}): string[];
/**
 * Translates an array of objects using indexed keys
 *
 * @param t - Translation function from useTranslation hook
 * @param keyPrefix - Base key prefix for the array (e.g., 'cases', 'items')
 * @param maxIndex - Maximum index to check (exclusive, so 4 means indices 0-3)
 * @param keys - Array of property keys to extract from each object (e.g., ['useCase', 'bestFit', 'dndev', 'reason'])
 * @returns Array of translated objects with missing translations filtered out
 *
 * @example
 * // JSON: { "cases": { "0": { "useCase": "...", "bestFit": "..." }, "1": {...} } }
 * const cases = translateObjectArray(t, 'cases', 4, ['useCase', 'bestFit', 'dndev', 'reason']);
 * // Result: [{ useCase: "...", bestFit: "...", dndev: "...", reason: "..." }, ...]
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function translateObjectArray<K extends string, T extends Record<K, string> = Record<K, string>>(t: TFunction, keyPrefix: string, maxIndex: number, keys: readonly K[]): T[];
/**
 * Translates an array with a specific range of indices
 *
 * @param t - Translation function from useTranslation hook
 * @param keyPrefix - Base key prefix for the array
 * @param startIndex - Starting index (inclusive)
 * @param endIndex - Ending index (exclusive)
 * @param options - Additional options for filtering
 * @returns Array of translated strings with missing translations filtered out
 *
 * @example
 * // Get items 2-5 (indices 2, 3, 4)
 * const items = translateArrayRange(t, 'items', 2, 5);
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function translateArrayRange(t: TFunction, keyPrefix: string, startIndex: number, endIndex: number, options?: {
    minLength?: number;
    excludeEmpty?: boolean;
    customFilter?: (item: string, index: number) => boolean;
}): string[];
/**
 * Translates an array and returns both the items and their original indices
 * Useful when you need to maintain the original index information
 *
 * @param t - Translation function from useTranslation hook
 * @param keyPrefix - Base key prefix for the array
 * @param maxIndex - Maximum index to check (exclusive)
 * @param options - Additional options for filtering
 * @returns Array of objects with item and originalIndex properties
 *
 * @example
 * // Get benefits with their original indices
 * const benefitsWithIndices = translateArrayWithIndices(t, 'benefits', 6);
 * // Result: [
 * //   { item: "value1", originalIndex: 0 },
 * //   { item: "value2", originalIndex: 1 },
 * //   { item: "value3", originalIndex: 2 }
 * // ]
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function translateArrayWithIndices(t: TFunction, keyPrefix: string, maxIndex: number, options?: {
    minLength?: number;
    excludeEmpty?: boolean;
    customFilter?: (item: string, index: number) => boolean;
}): Array<{
    item: string;
    originalIndex: number;
}>;

/**
 * @fileoverview Create document metadata utility
 * @description Creates metadata for a new document with timestamps and user IDs
 *
 * This utility provides a standardized way to create document metadata
 * for database operations, ensuring consistency across the application.
 *
 * **Metadata Fields:**
 * - `createdAt`: ISO timestamp when document was created
 * - `updatedAt`: ISO timestamp when document was last updated
 * - `createdById`: User ID who created the document
 * - `updatedById`: User ID who last updated the document
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 *
 * **Usage Pattern:**
 * ```typescript
 * const metadata = createMetadata(userId);
 * const document = { ...data, ...metadata };
 * ```
 *
 * **Database Integration:**
 * - Compatible with Firestore document structure
 * - Supports audit trails and user tracking
 * - Consistent timestamp format across all documents
 */
/**
 * Creates metadata for a new document with audit trail information
 *
 * **Purpose:** Provides standardized metadata for database documents
 * including creation timestamps and user tracking for audit purposes.
 *
 * **Features:**
 * - ISO timestamp format for consistency
 * - User ID tracking for audit trails
 * - Both creation and update fields initialized
 * - Ready for immediate database insertion
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param userId - The ID of the user creating the document
 * @returns Metadata object with timestamps and user IDs
 *
 * @example
 * ```typescript
 * const user = { id: 'user123', name: 'John Doe' };
 * const metadata = createMetadata(user.id);
 *
 * const newPost = {
 *   title: 'My Post',
 *   content: 'Post content...',
 *   ...metadata
 * };
 *
 * await firestore.collection('posts').add(newPost);
 * ```
 */
declare function createMetadata(userId: string): {
    createdAt: string;
    updatedAt: string;
    createdById: string;
    updatedById: string;
};

/**
 * @fileoverview Currency Formatting Utilities
 * @description Single mapping of ISO 4217 currency codes to locale and symbol. Top ~50 currencies.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/** Entry: 3-letter code → locale (for Intl) and display symbol */
interface CurrencyEntry {
    locale: string;
    symbol: string;
}
/**
 * Top ~50 currencies: 3-letter code, locale, symbol.
 * Unknown codes: getCurrencyLocale → 'en-US', getCurrencySymbol → code as-is.
 */
declare const CURRENCY_MAP: Record<string, CurrencyEntry>;
/**
 * Returns the locale for a currency code (for Intl formatting).
 * Unknown codes → 'en-US'.
 *
 * @param currencyCode - ISO 4217 currency code (e.g. 'EUR', 'USD')
 * @returns Locale string
 */
declare function getCurrencyLocale(currencyCode: string): string;
/**
 * Returns the symbol for a currency code (e.g. EUR → '€').
 * Unknown codes → code as-is (no validation).
 *
 * @param currencyCode - ISO 4217 currency code or any string
 * @returns Symbol string or the code itself
 */
declare function getCurrencySymbol(currencyCode: string): string;
/**
 * Format currency value with proper locale based on currency code
 *
 * @param value - Numeric value to format
 * @param currencyCode - ISO 4217 currency code
 * @param options - Additional Intl.NumberFormat options
 * @returns Formatted currency string
 *
 * @example
 * ```typescript
 * formatCurrency(12345, 'EUR') // → "12 345 €"
 * formatCurrency(12345, 'USD') // → "$12,345"
 * ```
 */
declare function formatCurrency(value: number | null | undefined, currencyCode: string, options?: Intl.NumberFormatOptions): string;

/**
 * @fileoverview Date utilities for consistent timestamp handling
 * @description Provides standardized date utilities for ISO string timestamps.
 * All date values in the framework should be ISO strings. Use these utilities to normalize any date input.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Convert compact date format (YYYYMMDD:HHMM) to ISO string
 * Format: 20251225:0000 → 2025-12-25T00:00:00.000Z
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param compactDate - Date in YYYYMMDD:HHMM format
 * @returns ISO string representation
 * @throws Error if format is invalid
 */
declare function compactToISOString(compactDate: string): string;
/**
 * Convert ISO string to compact date format (YYYYMMDD:HHMM)
 * Format: 2025-12-25T00:00:00.000Z → 20251225:0000
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param isoString - ISO date string
 * @returns Compact date string in YYYYMMDD:HHMM format
 * @throws Error if ISO string is invalid
 */
declare function isoToCompactString(isoString: string): string;
/**
 * Check if a string is in compact date format (YYYYMMDD:HHMM)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param value - String to check
 * @returns True if string matches YYYYMMDD:HHMM format
 */
declare function isCompactDateString(value: string): boolean;
/**
 * Normalize any date value to ISO string
 * Handles Date objects, ISO strings, compact format (YYYYMMDD:HHMM), timestamps (numbers), and Firestore Timestamps
 * This is the single source of truth for date normalization across the entire framework
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param date - Date value in any format (Date, string, number, FirestoreTimestamp)
 * @returns ISO string representation
 * @throws Error if date is invalid
 */
declare function normalizeToISOString(date: DateValue | number | null | undefined): string;
/**
 * Get current timestamp as ISO string
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @returns Current timestamp in ISO string format
 */
declare function getCurrentTimestamp(): string;
/**
 * Convert Date object to ISO string
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param date - Date object to convert
 * @returns ISO string representation
 */
declare function toISOString(date: Date): string;
/**
 * Convert timestamp (number) to ISO string
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param timestamp - Timestamp in milliseconds
 * @returns ISO string representation
 */
declare function timestampToISOString(timestamp: number): string;
/**
 * Calculate week number from ISO date string
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param isoString - ISO date string
 * @returns Week number and year as string (e.g., "Week 15, 2024")
 */
declare function getWeekFromISOString(isoString: string): string;
/**
 * Format a date as relative time (e.g., "5 minutes ago", "in 2 hours")
 * Uses native Intl.RelativeTimeFormat for locale-aware formatting.
 * Falls back to formatDate for dates older than threshold.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param date - Date value (ISO string, Date object, timestamp, or null/undefined)
 * @param locale - Locale string (e.g., "en", "fr", "de"). Defaults to "en"
 * @param options - Configuration options
 * @param options.style - "long" | "short" | "narrow". Defaults to "long"
 * @param options.numeric - "always" | "auto". Defaults to "auto" (allows "yesterday" instead of "1 day ago")
 * @param options.fallbackThreshold - Seconds after which to fall back to formatDate. Defaults to 1 week
 * @returns Localized relative time string or formatted date for old dates
 */
declare function formatRelativeTime(date: DateValue | number | null | undefined, locale?: string, options?: {
    style?: 'long' | 'short' | 'narrow';
    numeric?: 'always' | 'auto';
    fallbackThreshold?: number;
}): string;
/** Date format presets for common use cases */
type DateFormatPreset = 'full' | 'long' | 'medium' | 'short' | 'date-only' | 'time-only' | 'datetime';
/** Custom format options for fine-grained control */
interface DateFormatOptions {
    year?: 'numeric' | '2-digit';
    month?: 'numeric' | '2-digit' | 'long' | 'short' | 'narrow';
    day?: 'numeric' | '2-digit';
    weekday?: 'long' | 'short' | 'narrow';
    hour?: 'numeric' | '2-digit';
    minute?: 'numeric' | '2-digit';
    second?: 'numeric' | '2-digit';
    hour12?: boolean;
    timeZone?: string;
    timeZoneName?: 'long' | 'short';
}
/**
 * Format date to localized string with preset or custom options
 * Uses native Intl.DateTimeFormat for proper locale-aware formatting.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param date - Date value (ISO string, Date object, timestamp, FirestoreTimestamp, or null/undefined)
 * @param locale - Locale string (e.g., "en", "fr", "de"). Defaults to "en"
 * @param format - Preset name or custom options. Defaults to "long"
 * @returns Localized formatted date string, or empty string if date is invalid
 *
 * @example
 * formatDate('2025-05-05T00:00:00.000Z', 'en', 'full')    // "Monday, May 5, 2025"
 * formatDate('2025-05-05T00:00:00.000Z', 'fr', 'long')    // "5 mai 2025"
 * formatDate('2025-05-05T14:30:00.000Z', 'en', 'datetime') // "May 5, 2025, 02:30 PM"
 * formatDate(new Date(), 'de', { month: 'short', day: 'numeric' }) // "5. Mai"
 */
declare function formatDate(date: DateValue | number | string | null | undefined, locale?: string, format?: DateFormatPreset | DateFormatOptions): string;
/**
 * Leniently parse any date value to ISO string.
 * Accepts Date objects, ISO strings, timestamps, Firestore Timestamps, and common date formats.
 * Returns undefined for invalid/unparseable dates (never throws).
 *
 * Use this for form inputs, API responses, or any external data where format is uncertain.
 * For strict validation, use normalizeToISOString() which throws on invalid input.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param value - Any value that might be a date
 * @returns ISO string if parseable, undefined otherwise
 *
 * @example
 * parseDate(new Date())                    // "2025-12-28T10:30:00.000Z"
 * parseDate('2025-12-28')                  // "2025-12-28T00:00:00.000Z"
 * parseDate('Dec 28, 2025')                // "2025-12-28T00:00:00.000Z"
 * parseDate(1735384200000)                 // "2025-12-28T10:30:00.000Z"
 * parseDate({ toDate: () => new Date() }) // "2025-12-28T10:30:00.000Z" (Firestore)
 * parseDate('not a date')                  // undefined
 * parseDate(null)                          // undefined
 */
declare function parseDate(value: unknown): string | undefined;
/**
 * Convert date-only string to ISO with time set to noon UTC.
 * Useful for date inputs where you want to avoid timezone edge cases.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param dateString - Date string (e.g., "2025-12-28")
 * @returns ISO string with time set to 12:00:00.000Z, or undefined if invalid
 *
 * @example
 * parseDateToNoonUTC('2025-12-28') // "2025-12-28T12:00:00.000Z"
 */
declare function parseDateToNoonUTC(dateString: string): string | undefined;
/**
 * Extract date-only part from any date value (YYYY-MM-DD format).
 * Strips time component for date comparisons or display.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param date - Date value (ISO string, Date object, timestamp, or null/undefined)
 * @returns Date string in YYYY-MM-DD format, or empty string if invalid
 *
 * @example
 * toDateOnly('2025-12-28T14:30:00.000Z') // "2025-12-28"
 * toDateOnly(new Date())                  // "2025-12-28"
 */
declare function toDateOnly(date: DateValue | number | string | null | undefined): string;

/**
 * @fileoverview Firestore rule condition generator for stakeholder ownership
 * @description Given EntityOwnershipConfig, returns a rule condition string suitable for
 * allow read and allow update. Use the same condition for both (owners can read and update).
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Generates a Firestore rule condition for read and update based on ownership config.
 * Use the returned string in firestore.rules like:
 *
 *   allow read, update: if <generated>;
 *
 * The condition is: (publicCondition AND ...) OR request.auth.uid == resource.data.<ownerField1> OR ...
 *
 * @param ownership - Entity ownership config (ownerFields + optional publicCondition array)
 * @returns Rule condition expression string
 */
declare function generateFirestoreRuleCondition(ownership: EntityOwnershipConfig): string;

/**
 * @fileoverview Smart translation helper
 * @description Auto-detects translation keys vs raw strings
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Smart translation helper - auto-detects translation keys vs raw strings
 *
 * **How it works:**
 * - If string has no dots/colons → return as-is (plain string)
 * - If string has namespace prefix (e.g. "purchase:products.x") → try to translate
 * - If string has dots but no namespace → try to translate (i18next fallback returns original if missing)
 *
 * **Namespace handling:**
 * - "purchase:products.earlyBird.name" → translates from purchase namespace
 * - "products.earlyBird.name" → translates from current namespace
 * - "Early Bird Lifetime" → returns as-is
 *
 * **Use cases:**
 * 1. Simple apps: Pass plain strings, they render as-is
 * 2. i18n apps: Pass translation keys with namespace prefix
 * 3. Edge cases: "Dr. Smith" with dot → tries t(), fallback returns original ✅
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 *
 * @example
 * ```tsx
 * // Simple app
 * maybeTranslate(t, "Early Bird Lifetime") // → "Early Bird Lifetime"
 *
 * // i18n app with namespace
 * maybeTranslate(t, "purchase:products.earlyBird.name") // → "Accès Anticipé à Vie" (if FR)
 *
 * // i18n app without namespace
 * maybeTranslate(t, "products.earlyBird.name") // → "Accès Anticipé à Vie" (if FR)
 *
 * // Missing translation
 * maybeTranslate(t, "products.missing.key") // → "products.missing.key" (debug!)
 * ```
 */
declare function maybeTranslate(t: any, value?: string): string;

/**
 * @fileoverview PKCE (Proof Key for Code Exchange) utilities
 * @description Implements PKCE for OAuth 2.0 flows to enhance security
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Generate a cryptographically random code verifier
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @returns Base64URL-encoded code verifier
 */
declare function generateCodeVerifier(): string;
/**
 * Generate a code challenge from a code verifier
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param verifier The code verifier
 * @returns Promise resolving to Base64URL-encoded code challenge
 */
declare function generateCodeChallenge(verifier: string): Promise<string>;
/**
 * Generate a PKCE pair (code verifier and challenge)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @returns Promise resolving to PKCE pair
 */
declare function generatePKCEPair(): Promise<{
    codeVerifier: string;
    codeChallenge: string;
}>;
/**
 * Check if PKCE is supported by the current environment
 * @returns True if PKCE is supported
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function isPKCESupported(): boolean;
/**
 * Validate a code verifier format
 * @param verifier The code verifier to validate
 * @returns True if the verifier is valid
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateCodeVerifier(verifier: string): boolean;
/**
 * Validate a code challenge format
 * @param challenge The code challenge to validate
 * @returns True if the challenge is valid
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateCodeChallenge(challenge: string): boolean;

/**
 * @fileoverview Graceful initialization utilities
 * @description Wraps initialization with graceful error handling and degradation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Wraps initialization with graceful error handling
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param init - Async initialization function
 * @param fallback - Fallback function on error
 * @param featureName - Name of feature for logging
 * @returns Result or false on error
 */
declare function withGracefulDegradation<T>(init: () => Promise<T>, fallback: () => void, featureName: string): Promise<T | false>;

/**
 * Lazy import with caching
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param importFn - Dynamic import function
 * @param cacheKey - Cache key for this import
 * @returns Cached or fresh import result
 */
declare function lazyImport<T>(importFn: () => Promise<T>, cacheKey: string): Promise<T>;

/**

 * @fileoverview Role Hierarchy Utilities

 * @description Provides role-based access control with hierarchical permissions.

 * Implements a 4-level hierarchy: guest (0) < user (1) < admin (2) < super (3).

 *

 * **Hierarchy Rules:**

 * - Super can access: super, admin, user, and guest routes

 * - Admin can access: admin, user, and guest routes

 * - User can access: user and guest routes

 * - Guest can access: guest routes only

 *

 * **CSR/SSR/Server Safe:**

 * Pure function with no browser APIs or React dependencies.

 * Safe for use in Firebase Functions, API routes, and server-side rendering.

 *

 * @version 0.1.0

 * @since 0.0.1

 * @author AMBROISE PARK Consulting

 */
/**

 * Check if a user role has access to a required role based on hierarchy.

 *

 * Uses a 4-level hierarchy where higher roles inherit access to lower roles:

 * - Super (level 3) can access super, admin, user, and guest routes

 * - Admin (level 2) can access admin, user, and guest routes

 * - User (level 1) can access user and guest routes

 * - Guest (level 0) can access guest routes only

 *

 * Unknown roles default to level -1 (denied) for security.

 * Unknown required roles default to Infinity (always denied).

 *

 * @param userRole - The user's current role (e.g., 'super', 'admin', 'user', 'guest')

 * @param requiredRole - The role required to access the resource

 * @returns True if user has sufficient role level, false otherwise

 *

 * @example

 * ```typescript

 * // Admin accessing user route

 * hasRoleAccess('admin', 'user') // true

 *

 * // User accessing admin route

 * hasRoleAccess('user', 'admin') // false

 *

 * // Super accessing admin route

 * hasRoleAccess('super', 'admin') // true

 * ```

 *

 * @version 0.1.0

 * @since 0.0.1

 */
declare function hasRoleAccess(userRole: string | undefined, requiredRole: string): boolean;
/**
 * Extract canonical role from auth claims
 *
 * Handles:
 * - 'role' claim (primary)
 * - Boolean flags (isAdmin, isSuper) (legacy/convenience)
 * - Fallbacks to USER_ROLES.USER
 *
 * @param claims - Auth claims object
 * @returns Canonical role string
 */
declare function getRoleFromClaims(claims: Record<string, any>): string;

/**

 * @fileoverview Tier Hierarchy Utilities

 * @description Provides subscription tier-based access control with hierarchical permissions.

 * Uses tier levels from SubscriptionConfig (apps define their own) with COMMON_TIER_CONFIGS as fallback.

 *

 * **Hierarchy Rules:**

 * Higher tier levels inherit access to lower tier levels:

 * - Tier with level 2 can access tiers with level 2, 1, and 0

 * - Tier with level 1 can access tiers with level 1 and 0

 * - Tier with level 0 can access tier with level 0 only

 *

 * **CSR/SSR/Server Safe:**

 * Pure function with no browser APIs or React dependencies.

 * Safe for use in Firebase Functions, API routes, and server-side rendering.

 *

 * @version 0.1.0

 * @since 0.0.1

 * @author AMBROISE PARK Consulting

 */

/**

 * Check if a user tier has access to a required tier based on hierarchy.

 *

 * Uses tier levels from the provided config (or COMMON_TIER_CONFIGS as fallback).

 * Higher tier levels inherit access to lower tier levels.

 *

 * Unknown tiers default to level -1 (denied) for security.

 * Unknown required tiers default to Infinity (always denied).

 *

 * @param userTier - The user's current tier (e.g., 'pro', 'free', 'ai')

 * @param requiredTier - The tier required to access the resource

 * @param tierConfig - Optional custom tier configuration. If not provided, uses COMMON_TIER_CONFIGS

 * @returns True if user has sufficient tier level, false otherwise

 *

 * @example

 * ```typescript

 * // Pro accessing free route

 * hasTierAccess('pro', 'free') // true

 *

 * // Free accessing pro route

 * hasTierAccess('free', 'pro') // false

 *

 * // With custom config

 * const customConfig = {

 *   basic: { features: [], level: 0 },

 *   premium: { features: [], level: 1 }

 * };

 * hasTierAccess('premium', 'basic', customConfig) // true

 * ```

 *

 * @version 0.1.0

 * @since 0.0.1

 */
declare function hasTierAccess(userTier: string | undefined, requiredTier: string, tierConfig?: SubscriptionConfig['tiers']): boolean;

/**
 * @fileoverview Provider Registry
 * @description Central registration point for all pluggable backends (CRUD, auth, storage).
 * Call `configureProviders()` once at app startup so that `useCrud`, auth, and storage work.
 * All framework code uses `getProvider()` — no direct backend imports in app code.
 *
 * **Required:** Import your `config/providers` module from the root component (e.g. App.tsx)
 * before any component that uses `useCrud`, auth, or storage.
 *
 * @example Firebase (Vite)
 * ```typescript
 * // App.tsx
 * import './config/providers';
 * // ...
 * ```
 * ```typescript
 * // config/providers.ts
 * import { configureProviders } from '@donotdev/core';
 * import { FirestoreAdapter, FirebaseAuth, FirebaseStorageAdapter } from '@donotdev/firebase';
 * configureProviders({
 *   crud: new FirestoreAdapter(),
 *   auth: new FirebaseAuth(),
 *   storage: new FirebaseStorageAdapter(),
 * });
 * ```
 *
 * @example Supabase
 * ```typescript
 * import { configureProviders } from '@donotdev/core';
 * import { SupabaseCrudAdapter, SupabaseAuth, SupabaseStorageAdapter } from '@donotdev/supabase';
 * const supabase = createClient(url, anonKey);
 * configureProviders({
 *   crud: new SupabaseCrudAdapter(supabase),
 *   auth: new SupabaseAuth(supabase),
 *   storage: new SupabaseStorageAdapter(supabase, 'your-bucket'),
 * });
 * ```
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */

/**
 * Configure all providers for the framework.
 * Must be called once at app startup, before any component uses `useCrud`, auth, or storage.
 * Typically called from a dedicated module (e.g. `config/providers.ts`) imported by main.tsx.
 *
 * @param providers - At least `crud`; optionally `auth`, `storage`, `serverAuth`, `callable`
 * @throws Does not throw; logs a warning if called more than once (use `resetProviders()` in tests)
 */
declare function configureProviders(providers: DndevProviders): void;
/**
 * Get a configured provider by key.
 *
 * @param key - The provider key ('crud', 'auth', 'storage', 'serverAuth', 'callable')
 * @returns The provider instance
 * @throws If provider not configured
 */
declare function getProvider<K extends keyof DndevProviders>(key: K): NonNullable<DndevProviders[K]>;
/**
 * Check if a provider is configured.
 *
 * @param key - The provider key to check
 * @returns true if the provider is configured
 */
declare function hasProvider(key: keyof DndevProviders): boolean;
/**
 * Reset all providers. **Only for testing.**
 */
declare function resetProviders(): void;

/**
 * Get or create a singleton backed by `globalThis.__DNDEV_SINGLETONS__`.
 *
 * Use this for singletons that must be shared across packages or survive
 * bundler chunk splits (Vite pre-bundling, esbuild code-splitting, HMR).
 *
 * Module-level `let` singletons break when a bundler evaluates the same
 * module in two separate chunks - each gets its own `let`. `globalThis`
 * is process-wide and survives all of that.
 *
 * **When to use:**
 * - Registries shared between consumer code and framework internals
 *   (e.g. FieldRegistry, providers, auth instance)
 * - Any singleton where `registerX()` happens in one package and
 *   `getX()` happens in another
 *
 * **When NOT to use:**
 * - Server-only singletons (functions/, tooling/, mcp-server/) - no chunk splits
 * - File-local caches that are only read in the same file
 *
 * @param key - Unique key for this singleton (e.g. 'field-registry')
 * @param factory - Factory function called once to create the instance
 * @returns The singleton instance (existing or newly created)
 *
 * @example
 * ```typescript
 * // In FieldRegistry.ts
 * import { getGlobalSingleton } from '@donotdev/core';
 *
 * export function getFieldRegistry(): FieldRegistry {
 *   return getGlobalSingleton('field-registry', () => new FieldRegistry());
 * }
 *
 * // In providers.ts
 * let _providers = getGlobalSingleton('providers', () => ({ current: null }));
 * ```
 */
declare function getGlobalSingleton<T>(key: string, factory: () => T): T;
/**
 * Clear a global singleton. **Only for testing.**
 *
 * @param key - The singleton key to clear
 */
declare function clearGlobalSingleton(key: string): void;
/**
 * Creates a singleton getter function for a class or factory function
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param ClassOrFactory - Class constructor or factory function
 * @param args - Constructor arguments (if ClassOrFactory is a class)
 * @returns Function that returns the singleton instance
 */
declare function createSingleton<T>(ClassOrFactory: (new (...args: any[]) => T) | (() => T), ...args: any[]): () => T;
/**
 * Creates a singleton getter function for a class with parameters
 * This version allows passing parameters to the constructor
 *
 * @param ClassOrFactory - Class constructor or factory function
 * @returns Function that returns the singleton instance with parameters
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function createSingletonWithParams<T>(ClassOrFactory: (new (...args: any[]) => T) | ((...args: any[]) => T)): (...args: any[]) => T;
/**
 * Creates an async singleton getter function for async factory functions
 *
 * @param asyncFactory - Async factory function that returns a Promise<T>
 * @returns Function that returns a Promise<T> for the singleton instance
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function createAsyncSingleton<T>(asyncFactory: () => Promise<T>): () => Promise<T>;
/**
 * Creates a method proxy for a singleton getter
 * This allows direct method access without calling getInstance() first
 *
 * @param getInstance - Singleton getter function
 * @param methods - Array of method names to proxy
 * @returns Proxy object with direct method access
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function createMethodProxy<T extends object>(getInstance: () => T, methods: (keyof T)[]): T;
/**
 * Singleton manager for complex initialization scenarios
 * Provides async initialization with proper error handling
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare class SingletonManager {
    private static instances;
    private static initializing;
    private static initialized;
    /**
     * Get or create a singleton instance with async initialization
     *
     * @param key - Unique key for the singleton
     * @param factory - Factory function that returns the instance
     * @param options - Initialization options
     * @returns Promise that resolves to the singleton instance
     *
     * @version 0.1.0
     * @since 0.0.1
     * @author AMBROISE PARK Consulting
     */
    static getOrCreate<T>(key: string, factory: () => Promise<T> | T, options?: {
        ssrSafe?: boolean;
        timeout?: number;
        cacheFailures?: boolean;
        fallbackFactory?: () => T;
    }): Promise<T>;
    /**
     * Check if a singleton is initialized
     *
     * @param key - Singleton key
     * @returns True if initialized
     *
     * @version 0.1.0
     * @since 0.0.1
     * @author AMBROISE PARK Consulting
     */
    static isInitialized(key: string): boolean;
    /**
     * Clear a singleton instance (for testing)
     *
     * @param key - Singleton key
     *
     * @version 0.1.0
     * @since 0.0.1
     * @author AMBROISE PARK Consulting
     */
    static clear(key: string): void;
    /**
     * Clear all singleton instances (for testing)
     *
     * @version 0.1.0
     * @since 0.0.1
     * @author AMBROISE PARK Consulting
     */
    static clearAll(): void;
}

/**
 * @fileoverview Update document metadata utility
 * @description Creates update metadata for an existing document
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Creates update metadata for an existing document
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param userId - The ID of the user updating the document
 * @returns An object with update timestamp and user ID
 */
declare function updateMetadata(userId: string): {
    updatedAt: string;
    updatedById: string;
};

/**
 * @fileoverview Field visibility utility
 * @description Extracts visible field names from a Valibot schema based on user role.
 *
 * Uses 6-level hierarchical visibility system (leverages hasRoleAccess):
 *
 * Hierarchy: guest < user < admin < super
 *
 * - `guest`: Everyone (including unauthenticated)
 * - `user`: Authenticated users (see guest + user)
 * - `admin`: Admins (see guest + user + admin)
 * - `super`: Super admins (see guest + user + admin + super)
 * - `technical`: System fields (admins+ only, read-only in forms)
 * - `hidden`: Never exposed to client
 * - `owner`: Visible only when request.auth.uid matches one of entity.ownership.ownerFields on the document (requires options)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Determines if a field should be visible based on its visibility setting
 * and the user's role.
 *
 * Uses hasRoleAccess for hierarchical check:
 * - guest < user < admin < super
 *
 * Special cases:
 * - `technical`: Visible to admin and super only (read-only in forms)
 * - `hidden`: Never visible
 * - undefined: Treated as `guest` (visible to all)
 *
 * @param visibility - The field's visibility setting
 * @param userRole - The current user's role
 * @returns True if the field should be visible
 */
declare function isFieldVisible(visibility: Visibility | undefined, userRole: UserRole): boolean;
/**
 * Options for owner-level visibility (per-document check).
 */
interface GetVisibleFieldsOptions {
    documentData?: Record<string, unknown>;
    uid?: string;
    ownership?: EntityOwnershipConfig;
}
/**
 * Extracts the names of all fields from a Valibot object schema that should be visible
 * based on the user's role and optional ownership context (for visibility: 'owner').
 *
 * @param schema - The Valibot schema, expected to be an object schema (v.object)
 * @param userRole - The current user's role (guest, user, admin, super)
 * @param options - Optional: documentData, uid, ownership for owner-level visibility
 * @returns An array of visible field names
 */
declare function getVisibleFields(schema: v.BaseSchema<unknown, any, v.BaseIssue<unknown>> | dndevSchema<any>, userRole: UserRole, options?: GetVisibleFieldsOptions): string[];

/**
 * @fileoverview Field visibility filter utility
 * @description Filters document fields based on visibility and user role using a Valibot schema.
 *
 * Uses 6-level hierarchical visibility system:
 *
 * Hierarchy: guest < user < admin < super
 *
 * - `guest`: Everyone (including unauthenticated)
 * - `user`: Authenticated users (see guest + user)
 * - `admin`: Admins (see guest + user + admin)
 * - `super`: Super admins (see guest + user + admin + super)
 * - `technical`: System fields (admins+ only, read-only in forms)
 * - `hidden`: Never exposed to client
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Options for owner-level visibility (per-document check).
 * Pass documentData, uid, and ownership so fields with visibility: 'owner' are included when uid matches an owner field.
 */
type FilterVisibleFieldsOptions = GetVisibleFieldsOptions;
/**
 * Filters the fields of a data object based on visibility rules defined
 * in a Valibot schema and the user's role. When options (documentData, uid, ownership)
 * are provided, fields with visibility: 'owner' are included only if uid matches
 * one of ownership.ownerFields in documentData.
 *
 * @template T - The expected type of the data object
 * @param data - The document data object to filter
 * @param schema - The Valibot schema with visibility metadata on each field
 * @param userRole - The current user's role (guest, user, admin, super)
 * @param options - Optional: documentData, uid, ownership for owner-level visibility
 * @returns A new object containing only the fields visible to the user
 */
declare function filterVisibleFields<T extends Record<string, any>>(data: T | null | undefined, schema: v.BaseSchema<unknown, any, v.BaseIssue<unknown>> | dndevSchema<any>, userRole: UserRole, options?: FilterVisibleFieldsOptions): Partial<T>;

/**
 * @fileoverview Extract flat field names for card queries/schemas.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * SSOT for card field resolution. Returns a flat, deduplicated field name list.
 *
 * Fallback chain: `listCardFields` → `listFields` → all entity field keys.
 *
 * - `string[]` → returned as-is
 * - `ListCardLayout` → all slot arrays merged (deduplicated)
 * - `undefined` → falls back to `listFields`, then `Object.keys(fields)`
 */
declare function getListCardFieldNames(entity: {
    listCardFields?: string[] | ListCardLayout;
    listFields?: string[];
    fields?: Record<string, unknown>;
}): string[];

/**
 * @fileoverview Restricted visibility detection utility
 * @description Checks if any field in a schema has visibility more restrictive than 'guest'.
 * Used by CrudService to gate direct adapter access for non-public entities.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Returns true if any field in the schema declares a visibility level more
 * restrictive than 'guest' (i.e. 'user', 'owner', 'admin', 'super', 'technical', 'hidden').
 * Used by CrudService to gate direct adapter access for non-public entities.
 *
 * Handles wrapped schemas (pipe, nullable, optional, union) by traversing the
 * schema tree to find the underlying object entries. Returns false for schemas
 * that cannot be introspected (lazy, custom).
 *
 * @param schema - A Valibot schema or dndevSchema to inspect
 * @returns true if any field has restricted visibility
 *
 * @example
 * // Public entity — all fields guest visibility
 * hasRestrictedVisibility(PublicPostSchema) // false
 *
 * @example
 * // Private entity — email field is 'user' visibility
 * hasRestrictedVisibility(UserProfileSchema) // true
 *
 * @version 0.1.0
 * @since 0.0.1
 */
declare function hasRestrictedVisibility(schema: v.BaseSchema<unknown, any, v.BaseIssue<unknown>> | dndevSchema<any>): boolean;

/**
 * @fileoverview AuthHardening
 * @description Brute-force lockout + session timeout enforcement.
 * Covers SOC2 CC6.1 (authentication), CC6.2 (account lockout).
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

interface LockoutEntry {
    attempts: number;
    lastAttempt: number;
    /** null = not locked; number = locked until this timestamp */
    lockedUntil: number | null;
}
/** Configuration for brute-force lockout and session timeout enforcement. */
interface AuthHardeningConfig {
    /**
     * Max consecutive failed sign-in attempts before lockout.
     * @default 5
     */
    maxAttempts?: number;
    /**
     * Lockout duration in milliseconds.
     * @default 900_000 (15 minutes)
     */
    lockoutMs?: number;
    /**
     * Idle session timeout in milliseconds. After this period of inactivity,
     * the session is considered expired.
     * @default 28_800_000 (8 hours)
     */
    sessionTimeoutMs?: number;
}
/** Result of a lockout status check for an identifier. */
interface LockoutResult {
    attempts: number;
    locked: boolean;
    lockedUntil: number | null;
}
declare class AuthHardening implements AuthHardeningContext {
    private readonly store;
    private readonly maxAttempts;
    private readonly lockoutMs;
    /** Expose for auth adapters to enforce idle session timeout */
    readonly sessionTimeoutMs: number;
    constructor(config?: AuthHardeningConfig);
    /**
     * Call BEFORE a sign-in attempt.
     * @throws {Error} if the identifier is currently locked.
     */
    checkLockout(identifier: string): void;
    /**
     * Call AFTER a failed sign-in attempt.
     * @returns current attempt count and whether the account is now locked.
     */
    recordFailure(identifier: string): LockoutResult;
    private _evictExpired;
    /**
     * Call AFTER a successful sign-in — resets the failure counter.
     */
    recordSuccess(identifier: string): void;
    /**
     * Check if a session has expired based on last activity timestamp.
     * @param lastActivityMs - `Date.now()` at last activity
     */
    isSessionExpired(lastActivityMs: number): boolean;
    /** Current entry for an identifier (for audit logging). */
    getEntry(identifier: string): LockoutEntry | undefined;
}

/**
 * @fileoverview Condition Builder Engine
 * @description Fluent API for building field conditions and evaluating them at runtime.
 * Used for dynamic field visibility, disabled state, required state, and readonly state.
 *
 * @example
 * ```typescript
 * import { when, evaluateCondition } from '@donotdev/core';
 *
 * // Simple condition
 * const condition = when('productType').equals('car');
 * evaluateCondition(condition, { productType: 'car' }); // true
 *
 * // Combined conditions
 * const combined = when('type').equals('corporate')
 *   .or(when('groupSize').greaterThan(10));
 * evaluateCondition(combined, { type: 'individual', groupSize: 15 }); // true
 *
 * // On entity fields
 * { name: 'licensePlate', type: 'text', visibility: 'user',
 *   conditions: {
 *     visible: when('productType').equals('car'),
 *     required: when('productType').equals('car'),
 *   }
 * }
 * ```
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Evaluate a condition expression (node or group) against form values.
 *
 * @param condition - The condition expression or ConditionBuilder to evaluate
 * @param formValues - Current form values (flat object or nested for workflows)
 * @returns Whether the condition is satisfied
 *
 * @example
 * ```typescript
 * const cond = when('status').equals('active');
 * const result = evaluateCondition(cond, { status: 'active' }); // true
 * ```
 */
declare function evaluateCondition(condition: ConditionInput, formValues: Record<string, unknown>): boolean;
/**
 * Evaluate all conditions for a field and return the computed state.
 *
 * @param behavior - The ConditionalBehavior from the field definition
 * @param formValues - Current form values
 * @returns ConditionResult with visible/disabled/required/readonly booleans
 */
declare function evaluateFieldConditions(behavior: ConditionalBehavior | undefined, formValues: Record<string, unknown>): ConditionResult;
/**
 * Chainable condition builder.
 * Wraps a ConditionExpression and provides .or()/.and() combinators.
 * Implements ConditionBuilderLike from @donotdev/types.
 */
declare class ConditionBuilder {
    /** The underlying condition expression (serializable data) */
    readonly expression: ConditionExpression;
    constructor(expression: ConditionExpression);
    /** The discriminant for ConditionExpression — delegates to inner expression */
    get type(): ConditionExpression['type'];
    /** Combine with OR logic */
    or(other: ConditionExpression | ConditionBuilder): ConditionBuilder;
    /** Combine with AND logic */
    and(other: ConditionExpression | ConditionBuilder): ConditionBuilder;
}
/** Intermediate builder returned by when(field) — provides operator methods */
interface WhenFieldBuilder {
    /** Field equals value */
    equals(value: unknown): ConditionBuilder;
    /** Field does not equal value */
    notEquals(value: unknown): ConditionBuilder;
    /** Field value is in array */
    in(values: unknown[]): ConditionBuilder;
    /** Field value is not in array */
    notIn(values: unknown[]): ConditionBuilder;
    /** Field value is greater than */
    greaterThan(value: number): ConditionBuilder;
    /** Field value is less than */
    lessThan(value: number): ConditionBuilder;
    /** Field value is greater than or equal */
    greaterThanOrEqual(value: number): ConditionBuilder;
    /** Field value is less than or equal */
    lessThanOrEqual(value: number): ConditionBuilder;
    /** Field has a truthy value (not null, not empty, not false) */
    exists(): ConditionBuilder;
    /** Field has no value (null, empty, or false) */
    notExists(): ConditionBuilder;
    /** Field contains value (string includes or array includes) */
    contains(value: unknown): ConditionBuilder;
}
/**
 * Start building a condition for a field.
 *
 * @param field - Field name to evaluate (supports dot notation for nested/cross-step: 'step.field')
 * @returns Builder with operator methods
 *
 * @example
 * ```typescript
 * // Simple
 * when('type').equals('car')
 *
 * // Combined
 * when('type').equals('corporate').or(when('size').greaterThan(10))
 *
 * // Cross-step (workflows)
 * when('basics.productType').equals('physical')
 * ```
 */
declare function when(field: string): WhenFieldBuilder;
/**
 * Extract all field names referenced by a condition expression.
 * Useful for building dependency graphs and optimizing re-evaluation.
 *
 * @param condition - The condition expression or builder to analyze
 * @returns Set of field names (may include dot-notated paths)
 */
declare function getConditionDependencies(condition: ConditionExpression | ConditionBuilder): Set<string>;

/**
 * Sanitize a URL for use in href attributes.
 * Blocks javascript:, data:, vbscript: and other dangerous schemes.
 * Allows safe schemes and relative URLs.
 *
 * @param href - The URL to sanitize
 * @returns The original URL if safe, empty string if dangerous
 */
declare function sanitizeHref(href: string): string;

/**
 * @fileoverview Safari-safe UUID v4 generator
 * @description Generates RFC 4122 compliant v4 UUIDs using `crypto.getRandomValues()`,
 * which is available in ALL modern browsers (Safari 11+, Chrome 11+, Firefox 26+).
 *
 * `crypto.randomUUID()` requires Safari 15.4+ and a secure context.
 * This utility works everywhere `crypto.getRandomValues()` is available,
 * which covers every browser we support.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */
/**
 * Generate a cryptographically random UUID v4.
 *
 * Uses `crypto.getRandomValues()` (universal) instead of `crypto.randomUUID()`
 * (Safari 15.4+ only) for maximum browser compatibility.
 *
 * @returns UUID v4 string (e.g. "550e8400-e29b-41d4-a716-446655440000")
 *
 * @version 0.1.0
 * @since 0.1.0
 */
declare function generateUUID(): string;

/**
 * @fileoverview Timeout and abort utilities for async operations
 * @description Wraps promises with timeout and AbortSignal support.
 * Used by CRUD and storage adapters to enforce operation deadlines.
 *
 * @version 0.1.0
 * @since 0.5.0
 * @author AMBROISE PARK Consulting
 */
/** Default timeout for upload operations (30 seconds) */
declare const DEFAULT_UPLOAD_TIMEOUT = 30000;
/** Default timeout for CRUD operations (15 seconds) */
declare const DEFAULT_CRUD_TIMEOUT = 15000;
/**
 * Wrap a promise with a timeout and optional AbortSignal.
 *
 * - If timeout expires: rejects with a TimeoutError
 * - If signal aborts: rejects with an AbortError
 * - If promise resolves/rejects first: returns that result
 * - Cleans up all listeners on completion
 *
 * @param promise - The promise to wrap
 * @param timeoutMs - Timeout in milliseconds (0 or negative = no timeout)
 * @param signal - Optional AbortSignal
 * @returns The promise result
 */
declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, signal?: AbortSignal): Promise<T>;

/**
 * @fileoverview Server-side date utilities
 * @description Robust date calculation utilities for server environments
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Add months to a date with proper edge case handling
 * Fixes issues like Jan 31 + 1 month = March 3 (should be Feb 28/29)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function addMonths(date: Date, months: number): Date;
/**
 * Add years to a date with proper edge case handling
 * Fixes issues like Feb 29 + 1 year in non-leap year
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function addYears(date: Date, years: number): Date;
/**
 * Calculate subscription end date with proper edge case handling
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param duration - Duration string (e.g., '1month', '3months', '1year', 'lifetime')
 * @param startDate - Start date (defaults to now)
 * @returns ISO string of end date (required for Firestore compatibility)
 */
declare function calculateSubscriptionEndDate(duration: string, startDate?: Date): string;
/**
 * Get current date as ISO string (Firestore compatible)
 * @returns Current date as ISO string
 */
/**
 * Parse ISO string to Date object
 * @param isoString - ISO string to parse
 * @returns Date object
 */
declare function parseISODate(isoString: string): Date;

/**
 * @fileoverview Server-side validation utilities
 * @description Validation utilities for server environments
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Validate URL format
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param url - URL string to validate
 * @param name - Name for error message
 * @throws Error if URL is invalid
 */
declare function validateUrl(url: string, name?: string): string;
/**
 * Validate and sanitize metadata object
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param metadata - Metadata object to validate
 * @returns Sanitized metadata object
 */
declare function validateMetadata(metadata: Record<string, any>): Record<string, string>;
/**
 * Validate environment variable
 * @param name - Environment variable name
 * @param required - Whether the variable is required
 * @returns Environment variable value
 */
declare function validateEnvVar(name: string, required?: boolean): string;

/**
 * @fileoverview Server-side cookie utilities
 * @description Cookie parsing for SSR environments (Next.js, etc.)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/**
 * Parse a cookie from HTTP Cookie header string
 * Server-side equivalent of getCookie()
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 * @param cookieHeader - HTTP Cookie header string
 * @param name - Cookie name to extract
 * @returns Cookie value or null if not found
 *
 * @example
 * ```typescript
 * const consent = parseServerCookie(request.headers.cookie, 'dndev-cookie-consent');
 * ```
 */
declare function parseServerCookie(cookieHeader: string | undefined, name: string): string | null;

/**
 * @fileoverview Server-side utilities
 * @description Server-safe utilities that can be used in server environments
 *
 * This module exports only utilities that are safe to use in server contexts:
 * - Common utilities (no client-specific code)
 * - Server-specific utilities
 * - Error handling
 * - Platform detection (server-aware)
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
//# sourceMappingURL=index.d.ts.map

type index_d_AuthHardening = AuthHardening;
declare const index_d_AuthHardening: typeof AuthHardening;
type index_d_AuthHardeningConfig = AuthHardeningConfig;
declare const index_d_CURRENCY_MAP: typeof CURRENCY_MAP;
type index_d_ConditionBuilder = ConditionBuilder;
declare const index_d_ConditionBuilder: typeof ConditionBuilder;
type index_d_CurrencyEntry = CurrencyEntry;
declare const index_d_DEFAULT_CRUD_TIMEOUT: typeof DEFAULT_CRUD_TIMEOUT;
declare const index_d_DEFAULT_ERROR_MESSAGES: typeof DEFAULT_ERROR_MESSAGES;
declare const index_d_DEFAULT_UPLOAD_TIMEOUT: typeof DEFAULT_UPLOAD_TIMEOUT;
type index_d_DateFormatOptions = DateFormatOptions;
type index_d_DateFormatPreset = DateFormatPreset;
type index_d_DoNotDevError = DoNotDevError;
declare const index_d_DoNotDevError: typeof DoNotDevError;
type index_d_ErrorHandlerConfig = ErrorHandlerConfig;
type index_d_ErrorHandlerFunction = ErrorHandlerFunction;
type index_d_FilterVisibleFieldsOptions = FilterVisibleFieldsOptions;
type index_d_GetVisibleFieldsOptions = GetVisibleFieldsOptions;
type index_d_HandleErrorOptions = HandleErrorOptions;
type index_d_LockoutResult = LockoutResult;
type index_d_SingletonManager = SingletonManager;
declare const index_d_SingletonManager: typeof SingletonManager;
declare const index_d_addMonths: typeof addMonths;
declare const index_d_addYears: typeof addYears;
declare const index_d_calculateSubscriptionEndDate: typeof calculateSubscriptionEndDate;
declare const index_d_captureErrorToSentry: typeof captureErrorToSentry;
declare const index_d_clearGlobalSingleton: typeof clearGlobalSingleton;
declare const index_d_commonErrorCodeMappings: typeof commonErrorCodeMappings;
declare const index_d_compactToISOString: typeof compactToISOString;
declare const index_d_configureProviders: typeof configureProviders;
declare const index_d_createAsyncSingleton: typeof createAsyncSingleton;
declare const index_d_createErrorHandler: typeof createErrorHandler;
declare const index_d_createMetadata: typeof createMetadata;
declare const index_d_createMethodProxy: typeof createMethodProxy;
declare const index_d_createSingleton: typeof createSingleton;
declare const index_d_createSingletonWithParams: typeof createSingletonWithParams;
declare const index_d_detectErrorSource: typeof detectErrorSource;
declare const index_d_ensureSpreadable: typeof ensureSpreadable;
declare const index_d_evaluateCondition: typeof evaluateCondition;
declare const index_d_evaluateFieldConditions: typeof evaluateFieldConditions;
declare const index_d_filterVisibleFields: typeof filterVisibleFields;
declare const index_d_formatCurrency: typeof formatCurrency;
declare const index_d_formatDate: typeof formatDate;
declare const index_d_formatRelativeTime: typeof formatRelativeTime;
declare const index_d_generateCodeChallenge: typeof generateCodeChallenge;
declare const index_d_generateCodeVerifier: typeof generateCodeVerifier;
declare const index_d_generateFirestoreRuleCondition: typeof generateFirestoreRuleCondition;
declare const index_d_generatePKCEPair: typeof generatePKCEPair;
declare const index_d_generateUUID: typeof generateUUID;
declare const index_d_getConditionDependencies: typeof getConditionDependencies;
declare const index_d_getCurrencyLocale: typeof getCurrencyLocale;
declare const index_d_getCurrencySymbol: typeof getCurrencySymbol;
declare const index_d_getCurrentTimestamp: typeof getCurrentTimestamp;
declare const index_d_getGlobalSingleton: typeof getGlobalSingleton;
declare const index_d_getListCardFieldNames: typeof getListCardFieldNames;
declare const index_d_getProvider: typeof getProvider;
declare const index_d_getRoleFromClaims: typeof getRoleFromClaims;
declare const index_d_getVisibleFields: typeof getVisibleFields;
declare const index_d_getWeekFromISOString: typeof getWeekFromISOString;
declare const index_d_handleError: typeof handleError;
declare const index_d_hasProvider: typeof hasProvider;
declare const index_d_hasRestrictedVisibility: typeof hasRestrictedVisibility;
declare const index_d_hasRoleAccess: typeof hasRoleAccess;
declare const index_d_hasTierAccess: typeof hasTierAccess;
declare const index_d_isCompactDateString: typeof isCompactDateString;
declare const index_d_isFieldVisible: typeof isFieldVisible;
declare const index_d_isPKCESupported: typeof isPKCESupported;
declare const index_d_isoToCompactString: typeof isoToCompactString;
declare const index_d_lazyImport: typeof lazyImport;
declare const index_d_mapToDoNotDevError: typeof mapToDoNotDevError;
declare const index_d_maybeTranslate: typeof maybeTranslate;
declare const index_d_normalizeToISOString: typeof normalizeToISOString;
declare const index_d_parseDate: typeof parseDate;
declare const index_d_parseDateToNoonUTC: typeof parseDateToNoonUTC;
declare const index_d_parseISODate: typeof parseISODate;
declare const index_d_parseServerCookie: typeof parseServerCookie;
declare const index_d_resetProviders: typeof resetProviders;
declare const index_d_safeValidate: typeof safeValidate;
declare const index_d_sanitizeHref: typeof sanitizeHref;
declare const index_d_showNotification: typeof showNotification;
declare const index_d_timestampToISOString: typeof timestampToISOString;
declare const index_d_toDateOnly: typeof toDateOnly;
declare const index_d_toISOString: typeof toISOString;
declare const index_d_translateArray: typeof translateArray;
declare const index_d_translateArrayRange: typeof translateArrayRange;
declare const index_d_translateArrayWithIndices: typeof translateArrayWithIndices;
declare const index_d_translateObjectArray: typeof translateObjectArray;
declare const index_d_updateMetadata: typeof updateMetadata;
declare const index_d_validateCodeChallenge: typeof validateCodeChallenge;
declare const index_d_validateCodeVerifier: typeof validateCodeVerifier;
declare const index_d_validateEnvVar: typeof validateEnvVar;
declare const index_d_validateMetadata: typeof validateMetadata;
declare const index_d_validateUrl: typeof validateUrl;
declare const index_d_validateWithSchema: typeof validateWithSchema;
declare const index_d_when: typeof when;
declare const index_d_withErrorHandling: typeof withErrorHandling;
declare const index_d_withGracefulDegradation: typeof withGracefulDegradation;
declare const index_d_withTimeout: typeof withTimeout;
declare const index_d_wrapAuthError: typeof wrapAuthError;
declare const index_d_wrapCrudError: typeof wrapCrudError;
declare const index_d_wrapStorageError: typeof wrapStorageError;
declare namespace index_d {
  export { index_d_AuthHardening as AuthHardening, index_d_CURRENCY_MAP as CURRENCY_MAP, index_d_ConditionBuilder as ConditionBuilder, index_d_DEFAULT_CRUD_TIMEOUT as DEFAULT_CRUD_TIMEOUT, index_d_DEFAULT_ERROR_MESSAGES as DEFAULT_ERROR_MESSAGES, index_d_DEFAULT_UPLOAD_TIMEOUT as DEFAULT_UPLOAD_TIMEOUT, index_d_DoNotDevError as DoNotDevError, index_d_SingletonManager as SingletonManager, index_d_addMonths as addMonths, index_d_addYears as addYears, index_d_calculateSubscriptionEndDate as calculateSubscriptionEndDate, index_d_captureErrorToSentry as captureErrorToSentry, index_d_clearGlobalSingleton as clearGlobalSingleton, index_d_commonErrorCodeMappings as commonErrorCodeMappings, index_d_compactToISOString as compactToISOString, index_d_configureProviders as configureProviders, index_d_createAsyncSingleton as createAsyncSingleton, index_d_createErrorHandler as createErrorHandler, index_d_createMetadata as createMetadata, index_d_createMethodProxy as createMethodProxy, index_d_createSingleton as createSingleton, index_d_createSingletonWithParams as createSingletonWithParams, index_d_detectErrorSource as detectErrorSource, index_d_ensureSpreadable as ensureSpreadable, index_d_evaluateCondition as evaluateCondition, index_d_evaluateFieldConditions as evaluateFieldConditions, index_d_filterVisibleFields as filterVisibleFields, index_d_formatCurrency as formatCurrency, index_d_formatDate as formatDate, index_d_formatRelativeTime as formatRelativeTime, index_d_generateCodeChallenge as generateCodeChallenge, index_d_generateCodeVerifier as generateCodeVerifier, index_d_generateFirestoreRuleCondition as generateFirestoreRuleCondition, index_d_generatePKCEPair as generatePKCEPair, index_d_generateUUID as generateUUID, index_d_getConditionDependencies as getConditionDependencies, index_d_getCurrencyLocale as getCurrencyLocale, index_d_getCurrencySymbol as getCurrencySymbol, index_d_getCurrentTimestamp as getCurrentTimestamp, index_d_getGlobalSingleton as getGlobalSingleton, index_d_getListCardFieldNames as getListCardFieldNames, index_d_getProvider as getProvider, index_d_getRoleFromClaims as getRoleFromClaims, index_d_getVisibleFields as getVisibleFields, index_d_getWeekFromISOString as getWeekFromISOString, index_d_handleError as handleError, index_d_hasProvider as hasProvider, index_d_hasRestrictedVisibility as hasRestrictedVisibility, index_d_hasRoleAccess as hasRoleAccess, index_d_hasTierAccess as hasTierAccess, index_d_isCompactDateString as isCompactDateString, index_d_isFieldVisible as isFieldVisible, index_d_isPKCESupported as isPKCESupported, index_d_isoToCompactString as isoToCompactString, index_d_lazyImport as lazyImport, index_d_mapToDoNotDevError as mapToDoNotDevError, index_d_maybeTranslate as maybeTranslate, index_d_normalizeToISOString as normalizeToISOString, index_d_parseDate as parseDate, index_d_parseDateToNoonUTC as parseDateToNoonUTC, index_d_parseISODate as parseISODate, index_d_parseServerCookie as parseServerCookie, index_d_resetProviders as resetProviders, index_d_safeValidate as safeValidate, index_d_sanitizeHref as sanitizeHref, index_d_showNotification as showNotification, index_d_timestampToISOString as timestampToISOString, index_d_toDateOnly as toDateOnly, index_d_toISOString as toISOString, index_d_translateArray as translateArray, index_d_translateArrayRange as translateArrayRange, index_d_translateArrayWithIndices as translateArrayWithIndices, index_d_translateObjectArray as translateObjectArray, index_d_updateMetadata as updateMetadata, index_d_validateCodeChallenge as validateCodeChallenge, index_d_validateCodeVerifier as validateCodeVerifier, index_d_validateEnvVar as validateEnvVar, index_d_validateMetadata as validateMetadata, index_d_validateUrl as validateUrl, index_d_validateWithSchema as validateWithSchema, index_d_when as when, index_d_withErrorHandling as withErrorHandling, index_d_withGracefulDegradation as withGracefulDegradation, index_d_withTimeout as withTimeout, index_d_wrapAuthError as wrapAuthError, index_d_wrapCrudError as wrapCrudError, index_d_wrapStorageError as wrapStorageError };
  export type { index_d_AuthHardeningConfig as AuthHardeningConfig, index_d_CurrencyEntry as CurrencyEntry, index_d_DateFormatOptions as DateFormatOptions, index_d_DateFormatPreset as DateFormatPreset, index_d_ErrorHandlerConfig as ErrorHandlerConfig, index_d_ErrorHandlerFunction as ErrorHandlerFunction, index_d_FilterVisibleFieldsOptions as FilterVisibleFieldsOptions, index_d_GetVisibleFieldsOptions as GetVisibleFieldsOptions, index_d_HandleErrorOptions as HandleErrorOptions, index_d_LockoutResult as LockoutResult };
}

/**
 * @fileoverview Schema enhancement utility
 * @description Enhances a Valibot schema with additional metadata
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Enhances a Valibot schema with additional metadata.
 *
 * @param schema - The base Valibot schema
 * @param metadata - The metadata to attach
 * @returns The enhanced schema
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function enhanceSchema<T>(schema: v.BaseSchema<unknown, T, v.BaseIssue<unknown>>, metadata: SchemaMetadata): dndevSchema<T>;

/**
 * @fileoverview Schema type generation utility
 * @description Creates Valibot schemas via registry - extensible for custom types
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Schema generator function type
 */
type CustomSchemaGenerator = (field: EntityField<FieldType>) => v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>> | null;
/**
 * Register a schema generator for a field type
 */
declare function registerSchemaGenerator(type: string, generator: CustomSchemaGenerator): void;
/**
 * Check if a schema generator is registered
 */
declare function hasCustomSchemaGenerator(type: string): boolean;
/**
 * Get all registered schema types
 */
declare function getRegisteredSchemaTypes(): string[];
/**
 * Clear all schema generators (testing)
 */
declare function clearSchemaGenerators(): void;
/**
 * Schema generators exported for unified registry
 * These are also auto-registered below for backward compatibility
 */
declare const textSchema: CustomSchemaGenerator;
declare const emailSchema: CustomSchemaGenerator;
declare const passwordSchema: CustomSchemaGenerator;
declare const urlSchema: CustomSchemaGenerator;
declare const numberSchema: CustomSchemaGenerator;
declare const booleanSchema: CustomSchemaGenerator;
declare const dateSchema: CustomSchemaGenerator;
declare const fileSchema: CustomSchemaGenerator;
declare const filesSchema: CustomSchemaGenerator;
declare const pictureSchema: CustomSchemaGenerator;
declare const picturesSchema: CustomSchemaGenerator;
declare const geopointSchema: CustomSchemaGenerator;
declare const addressSchema: CustomSchemaGenerator;
declare const mapSchema: CustomSchemaGenerator;
declare const arraySchema: CustomSchemaGenerator;
declare const selectSchema: CustomSchemaGenerator;
declare const multiselectSchema: CustomSchemaGenerator;
declare const referenceSchema: CustomSchemaGenerator;
declare const stringSchema: CustomSchemaGenerator;
declare const telSchema: CustomSchemaGenerator;
declare const ibanSchema: CustomSchemaGenerator;
declare const neverSchema: CustomSchemaGenerator;
declare const switchSchema: CustomSchemaGenerator;
declare const gdprConsentSchema: CustomSchemaGenerator;
declare const priceSchema: CustomSchemaGenerator;
/**
 * Get Valibot schema for an entity field
 *
 * Priority order:
 * 1. field.validation?.schema (custom schema defined directly in entity)
 * 2. Registry lookup (built-in or registered custom types)
 * 3. Fallback to v.unknown() for unregistered types
 */
declare function getSchemaType(field: EntityField<FieldType>): v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>;

/**
 * Recursively validates that all string values that look like potential dates
 * within an object adhere to the ISO 8601 format (YYYY-MM-DDTHH:mm:ss.sssZ).
 *
 * @param data - The object or data structure to validate
 * @param {string} [currentPath=''] - Internal tracking of the object path for error messages
 * @throws Error if any string resembling a date is not in the correct ISO format
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateDates(data: Record<string, unknown> | unknown[], currentPath?: string): void;

/**
 * Validates a document against the schema, including uniqueness and custom validations.
 * @param schema - The enhanced schema.
 * @param data - The document data.
 * @param operation - 'create' or 'update'.
 * @param currentDocId - Optional current document ID for update operations.
 * @throws DoNotDevError if validation fails.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateDocument<T>(schema: dndevSchema<T>, data: Record<string, unknown>, operation: 'create' | 'update', currentDocId?: string): Promise<void>;

/**
 * @fileoverview Unique field validation utility
 * @description Validates uniqueness constraints for schema fields
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Registers a validator for uniqueness constraints
 *
 * @param validator - The validator implementation
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function registerUniqueConstraintValidator(validator: UniqueConstraintValidator): void;
/**
 * Validates unique fields for a document across environments.
 *
 * @param schema - The Valibot schema with metadata.
 * @param data - The document data.
 * @param currentDocId - Optional ID of the current document (for updates).
 * @throws Error if a unique constraint is violated.
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function validateUniqueFields<T>(schema: dndevSchema<T>, data: Record<string, unknown>, currentDocId?: string): Promise<void>;

/**
 * @fileoverview Schema Utilities
 * @description Common utility functions for working with schemas. Provides helper functions for schema metadata checking and manipulation.
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Checks if an object has schema metadata (works with Valibot schemas)
 *
 * @param obj - The object to check
 * @returns Whether the object has schema metadata
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function hasMetadata(obj: unknown): obj is dndevSchema<unknown>;
/**
 * Gets the collection name from a schema
 *
 * @param schema - The schema to get the collection name from
 * @returns The collection name
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function getCollectionName(schema: dndevSchema<unknown>): string;

/**
 * @fileoverview The 4 Field Families
 * @description Every entity in the framework is composed of 4 families
 *
 * ## The 4 Families
 *
 * ```
 * Entity = Technical Fields + Status Field + User Fields (Framework Types or Custom Types)
 * ```
 *
 * ### Family 1: TECHNICAL_FIELDS (Backend-Generated)
 * **Members**: `id`, `createdAt`, `updatedAt`, `createdById`, `updatedById`
 *
 * **Rules**:
 * - ✓ Always present (framework adds automatically)
 * - ✗ Users cannot set (stripped from submissions)
 * - ✓ Read-only in edit forms
 * - ✓ Auto-generated by server
 *
 * ### Family 2: STATUS_FIELD (Lifecycle Management)
 * **Member**: `status`
 *
 * **Default Values**: `'draft'`, `'available'`, `'deleted'`
 *
 * **Rules**:
 * - ✓ Always present (framework adds)
 * - ✓ Users must set value
 * - ✓ Users can add custom values (`'reserved'`, `'sold'`)
 * - ✗ Cannot remove default values
 * - ✓ Draft mode (`status === 'draft'`) relaxes validation
 *
 * ### Family 3: FRAMEWORK_TYPES (~30 Built-in)
 * **Available Types**:
 * - Text: `text`, `textarea`, `email`, `tel`, `url`, `password`
 * - Numbers: `number`, `range`
 * - Dates: `date`, `datetime-local`, `time`, `timestamp`
 * - Choices: `select`, `multiselect`, `radio`, `checkbox`, `combobox`, `switch`
 * - Media: `image`, `images`, `file`
 * - Special: `reference`, `geopoint`, `address`, `map`
 *
 * ### Family 4: CUSTOM_TYPES (User-Registered)
 * **What**: Custom field types registered via `registerFieldType()`
 *
 * **Examples**: `repairOperations`, `ratp`, custom widgets
 *
 * ## Complete Example
 *
 * ```typescript
 * import { defineEntity } from '@donotdev/core';
 * import { registerFieldType } from '@donotdev/crud';
 *
 * // Register custom type (Family 4)
 * registerFieldType('repairOperations', {
 *   schema: (field) => v.array(v.object({ operation: v.string(), cost: v.number() })),
 *   component: RepairOperationsField
 * });
 *
 * // Define entity
 * const carEntity = defineEntity({
 *   name: 'Car',
 *   collection: 'cars',
 *   fields: {
 *     // User fields using FRAMEWORK_TYPES (Family 3)
 *     make: { type: 'text', validation: { required: true } },
 *     year: { type: 'number' },
 *     images: { type: 'images' },
 *     fuelType: { type: 'select', validation: { options: [...] } },
 *
 *     // User field using CUSTOM_TYPES (Family 4)
 *     repairs: { type: 'repairOperations', visibility: 'admin' },
 *
 *     // Extend STATUS_FIELD (Family 2)
 *     status: {
 *       validation: {
 *         options: [
 *           { value: 'reserved', label: 'Reserved' },
 *           { value: 'sold', label: 'Sold' }
 *         ]
 *       }
 *     }
 *
 *     // TECHNICAL_FIELDS (Family 1) auto-added by framework
 *   }
 * });
 * ```
 *
 * **Result**:
 * - Family 1 (Technical): `id`, `createdAt`, `updatedAt`, `createdById`, `updatedById`
 * - Family 2 (Status): `status` with `draft/available/deleted/reserved/sold`
 * - User fields: `make`, `year`, `images`, `fuelType`, `repairs`
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Type-safe base fields that all entities inherit
 * Each field has its specific type for proper TypeScript inference
 */
interface TypedBaseFields {
    id: EntityField<'text'>;
    createdAt: EntityField<'timestamp'>;
    updatedAt: EntityField<'timestamp'>;
    createdById: EntityField<'reference'>;
    updatedById: EntityField<'reference'>;
    status: EntityField<'select'>;
}
/**
 * Default status options for draft/publish/delete workflow
 * Framework provides 'draft', 'available', 'deleted' - consumers can extend
 *
 * Translation fallback order: entity-{name} → crud (never dndev)
 * - Framework defaults: crud:status.draft, crud:status.available, crud:status.deleted
 * - User overrides: entity-{name}_*.json files (e.g., entity-inquiry_en.json: "status.draft": "New")
 *
 * CRUD is optional and shouldn't pollute core framework (dndev) namespace
 */
declare const DEFAULT_STATUS_OPTIONS: readonly [{
    readonly value: "draft";
    readonly label: "crud:status.draft";
}, {
    readonly value: "available";
    readonly label: "crud:status.available";
}, {
    readonly value: "deleted";
    readonly label: "crud:status.deleted";
}];
/**
 * Default status value for new documents (visible immediately).
 * Forms use 'draft' explicitly for save-and-finish-later flows.
 */
declare const DEFAULT_STATUS_VALUE: "available";
/**
 * Statuses that are hidden from non-admin users
 */
declare const HIDDEN_STATUSES: readonly ["draft", "deleted"];
/**
 * Fields that are TRULY backend-generated (cannot be set by user)
 * These are stripped from create operations - backend creates them automatically
 *
 * @category Field Families
 * @constant BACKEND_GENERATED_FIELD_NAMES
 */
declare const BACKEND_GENERATED_FIELD_NAMES: readonly ["id", "createdAt", "updatedAt", "createdById", "updatedById"];
/**
 * List of technical field names that are auto-generated by the backend
 * Includes backend-generated fields + status field
 *
 * These fields are optional in create schemas (backend creates them automatically).
 * They can be updated in update operations if provided.
 *
 * **Note**: Status is included here for visibility/editability logic but is NOT stripped
 * from form submissions since users MUST set it. Use BACKEND_GENERATED_FIELD_NAMES for stripping.
 *
 * @category Field Families
 * @constant TECHNICAL_FIELD_NAMES
 */
declare const TECHNICAL_FIELD_NAMES: readonly ["id", "createdAt", "updatedAt", "createdById", "updatedById", "status"];
/**
 * TypeScript Helper Types for Field Families
 * @category Field Families
 */
/** Type for backend-generated field names */
type BackendGeneratedField = (typeof BACKEND_GENERATED_FIELD_NAMES)[number];
/** Type for the status field */
type StatusField = 'status';
/** Type for all technical field names */
type TechnicalField = (typeof TECHNICAL_FIELD_NAMES)[number];
/**
 * Type guard to check if a field name is a framework-managed field
 * @param fieldName - Field name to check
 * @returns True if field is in TECHNICAL_FIELD_NAMES
 *
 * @example
 * ```typescript
 * if (isFrameworkField('status')) {
 *   // Field is framework-managed (cannot remove)
 * }
 * ```
 */
declare function isFrameworkField(fieldName: string): fieldName is TechnicalField;
/**
 * Type guard to check if a field is backend-generated
 * @param fieldName - Field name to check
 * @returns True if field is auto-generated by backend
 *
 * @example
 * ```typescript
 * if (isBackendGeneratedField('createdAt')) {
 *   // Field is backend-generated (should be stripped on create)
 * }
 * ```
 */
declare function isBackendGeneratedField(fieldName: string): fieldName is BackendGeneratedField;
declare const baseFields: TypedBaseFields;

/**
 * Defines an entity with validation and default configuration
 *
 * Automatically adds technical fields (`id`, `createdAt`, `updatedAt`, `createdById`, `updatedById`)
 * with `visibility: 'technical'`. User-defined technical fields are merged with defaults, allowing
 * customization (e.g., `editable: 'admin'`, custom `label`, additional `validation`).
 *
 * @param entity - The business entity definition
 * @returns The validated and configured entity
 *
 * @example
 * ```typescript
 * export const productEntity = defineEntity({
 *   name: 'Product',
 *   collection: 'products',
 *   fields: {
 *     name: {
 *       type: 'text',
 *       visibility: 'user',
 *       validation: { required: true, minLength: 3 }
 *     },
 *     // Customize technical field (optional)
 *     createdAt: {
 *       editable: 'admin',
 *       label: 'Created Date'
 *     }
 *   },
 *   // Override access defaults (optional)
 *   access: { create: 'guest' }  // Public inquiry form
 * });
 * ```
 *
 * **Technical Fields:**
 * - Automatically added: `id`, `createdAt`, `updatedAt`, `createdById`, `updatedById`, `status`
 * - Default: `visibility: 'technical'`, read-only in edit forms
 * - Customizable: Can override `editable`, `label`, `hint`, `validation` (merged with defaults)
 *
 * **Access Configuration:**
 * - Defaults: `{ read: 'guest', create: 'admin', update: 'admin', delete: 'admin' }`
 * - Uses role hierarchy: guest (0) < user (1) < admin (2) < super (3)
 * - Override individual operations: `access: { create: 'guest' }` for public forms
 * - Field visibility still applies for sensitive data filtering
 *
 * **Status Field (Draft/Publish/Delete):**
 * - Auto-added with `visibility: 'admin'` and options: `['draft', 'available', 'deleted']`
 * - Default value: `'available'` (new documents are published by default)
 * - `draft` and `deleted` statuses hidden from non-admin users (server-side filtering)
 * - `validation.required` on other fields only enforced when status !== 'draft'
 * - Extend options: `status: { validation: { options: [{ value: 'sold', label: 'sold' }] } }`
 * - Hide field: `status: { visibility: 'technical' }` if you don't want it in forms
 *
 * **Dropdown Options Format:**
 * - For `select`, `multiselect`, and `radio` field types, options must be defined in `validation.options`
 * - Options must be an array of objects with `value` (string) and `label` (string)
 * - Labels can use i18n keys (e.g., `'entities.product.status.active'`) for translation
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
declare function defineEntity<const F extends Record<string, EntityField>>(entity: Omit<BusinessEntity<F>, 'fields'> & {
    fields: F;
}): Entity<MutableMergedEntityFieldMap<F>>;

/**
 * @fileoverview Unified Schema Generation
 * @description Creates Valibot schemas from entity definitions with visibility metadata.
 *
 * Entity → Schema (with visibility) → Used everywhere (frontend + backend)
 *
 * Isomorphic code (works in both client and server environments).
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */

/**
 * Valibot schema with visibility metadata attached
 */
interface SchemaWithVisibility extends v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>> {
    visibility?: Visibility;
}
/**
 * Operation-specific schemas generated from entity
 */
interface OperationSchemas {
    /** Create: excludes technical fields, enforces required */
    create: dndevSchema<unknown>;
    /** Draft: excludes technical fields, all optional except status='draft' */
    draft: dndevSchema<unknown>;
    /** Update: excludes technical fields, all optional */
    update: dndevSchema<unknown>;
    /** Get: includes all fields with visibility metadata */
    get: dndevSchema<unknown>;
    /** List: optimized for admin table (uses listFields) */
    list: dndevSchema<unknown>;
    /** ListCard: optimized for public cards (uses listCardFields, falls back to listFields) */
    listCard: dndevSchema<unknown>;
    /** Delete: just { id: string } */
    delete: dndevSchema<unknown>;
}
/**
 * Creates all operation-specific schemas from an entity definition
 *
 * Each schema field has `.visibility` attached for backend filtering.
 *
 * @param entity - Entity definition
 * @returns Operation-specific schemas with visibility metadata
 *
 * @example
 * ```typescript
 * const schemas = createSchemas(carEntity);
 * // schemas.create - for creating documents
 * // schemas.draft - for saving incomplete
 * // schemas.update - for partial updates
 * // schemas.get - for reading (includes technical fields)
 * // schemas.list - array of get
 * // schemas.delete - just { id }
 * ```
 */
declare function createSchemas(entity: AnyEntity): OperationSchemas;

/**
 * @fileoverview Option generation helpers for select fields
 * @description Simple utilities to generate options arrays for select/dropdown fields.
 * These are isomorphic and can be used in entity definitions (shared by client and server).
 *
 * @version 0.1.0
 * @since 0.0.1
 * @author AMBROISE PARK Consulting
 */
/** Standard option format for select fields */
interface SelectOption {
    value: string;
    label: string;
}
/**
 * Generates numeric range options for a select field.
 *
 * @param start - First number in the range
 * @param end - Last number in the range
 * @param step - Increment between numbers (default: 1)
 * @param descending - Whether to sort descending (default: false)
 * @returns Array of options with value and label
 *
 * @example
 * ```ts
 * // Quantities 1-10
 * options: rangeOptions(1, 10)
 *
 * // Percentages 0-100 by 10
 * options: rangeOptions(0, 100, 10)
 * ```
 */
declare function rangeOptions(start: number, end: number, step?: number, descending?: boolean): SelectOption[];

/**
 * @fileoverview Scope Provider Registry for Multi-Tenancy
 * @description Global registry for scope providers that supply tenant/company/workspace IDs
 * to CRUD operations. Apps register providers once, entities declare which provider to use.
 *
 * @example
 * ```typescript
 * // 1. App registers scope provider (once, at startup)
 * import { registerScopeProvider } from '@donotdev/core';
 * import { useCurrentCompanyStore } from './stores/currentCompanyStore';
 *
 * registerScopeProvider('company', () =>
 *   useCurrentCompanyStore.getState().currentCompanyId
 * );
 *
 * // 2. Entity declares scope
 * const clientEntity = defineEntity({
 *   name: 'Client',
 *   collection: 'clients',
 *   scope: { field: 'companyId', provider: 'company' },
 *   fields: { ... }
 * });
 *
 * // 3. CRUD operations auto-inject/filter by scope (transparent)
 * const { add } = useCrud(clientEntity);
 * await add({ name: 'Acme' }); // companyId auto-injected
 * ```
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
/**
 * Function that returns the current scope ID from app state
 * Returns null if no scope is currently selected (e.g., no company selected)
 */
type ScopeProviderFn = () => string | null;
/**
 * Register a scope provider function
 *
 * Call this once at app startup to register scope providers.
 * The provider function should return the current scope ID from your app's state.
 *
 * @param name - Provider name (e.g., 'company', 'tenant', 'workspace')
 * @param provider - Function that returns the current scope ID
 *
 * @example
 * ```typescript
 * // Using Zustand store
 * registerScopeProvider('company', () =>
 *   useCurrentCompanyStore.getState().currentCompanyId
 * );
 *
 * // Using React context (via ref)
 * const companyIdRef = { current: null };
 * registerScopeProvider('company', () => companyIdRef.current);
 * // Update ref in your context provider
 * ```
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
declare function registerScopeProvider(name: string, provider: ScopeProviderFn): void;
/**
 * Unregister a scope provider (for testing or cleanup)
 *
 * @param name - Provider name to unregister
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
declare function unregisterScopeProvider(name: string): void;
/**
 * Get the current scope value from a registered provider
 *
 * Used internally by CRUD operations to inject/filter by scope.
 *
 * @param providerName - Name of the registered provider
 * @returns Current scope ID, or null if not available
 *
 * @example
 * ```typescript
 * const companyId = getScopeValue('company');
 * if (!companyId) {
 *   throw new Error('No company selected');
 * }
 * ```
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
declare function getScopeValue(providerName: string): string | null;
/**
 * Check if a scope provider is registered
 *
 * @param providerName - Name of the provider to check
 * @returns True if provider is registered
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
declare function hasScopeProvider(providerName: string): boolean;
/**
 * Get all registered scope provider names (for debugging)
 *
 * @returns Array of registered provider names
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
declare function getRegisteredScopeProviders(): string[];
/**
 * Clear all scope providers (for testing)
 *
 * @version 0.1.0
 * @since 0.0.4
 * @author AMBROISE PARK Consulting
 */
declare function clearScopeProviders(): void;

/**
 * @fileoverview Bulk CRUD wire schemas
 * @description Valibot schemas for the transactional bulk endpoint
 *   `POST /api/crud/:collection/bulk`. These are on-the-wire validators only —
 *   row shapes are kept opaque (`record<string, unknown>`) because per-entity
 *   validation is performed upstream by the CRUD service against the entity's
 *   generated `create` / `update` schemas. Isomorphic (client + server).
 *
 * @version 0.1.0
 * @since 0.2.0
 * @author AMBROISE PARK Consulting
 */

/**
 * Opaque insert row schema.
 *
 * The bulk endpoint does not know the entity at parse time; per-field
 * validation is delegated to the CRUD service using the entity's `create`
 * schema. We only enforce the structural invariant: each insert is an object.
 *
 * @example
 * import * as v from 'valibot';
 * import { BulkInsertSchema } from '@donotdev/schemas';
 *
 * v.parse(BulkInsertSchema, { name: 'Alice', age: 30 });
 */
declare const BulkInsertSchema: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
/**
 * Opaque update row schema: `{ id, patch }`.
 *
 * `patch` keeps field-level validation deferred to the entity's `update`
 * schema, mirroring how single-row `update()` accepts a partial payload.
 *
 * @example
 * import * as v from 'valibot';
 * import { BulkUpdateSchema } from '@donotdev/schemas';
 *
 * v.parse(BulkUpdateSchema, { id: 'abc', patch: { name: 'Bob' } });
 */
declare const BulkUpdateSchema: v.ObjectSchema<{
    readonly id: v.StringSchema<undefined>;
    readonly patch: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
}, undefined>;
/**
 * Opaque delete-id schema — a single document id.
 *
 * @example
 * import * as v from 'valibot';
 * import { BulkDeleteIdSchema } from '@donotdev/schemas';
 *
 * v.parse(BulkDeleteIdSchema, 'doc-123');
 */
declare const BulkDeleteIdSchema: v.StringSchema<undefined>;
/**
 * Wire schema for `POST /:collection/bulk` request body.
 *
 * All three op arrays are optional so clients can submit any subset.
 * An empty object `{}` is a valid no-op payload — the service short-circuits
 * and returns empty arrays without hitting the database.
 *
 * Per the bulk contract (see `BULK_CRUD_TODO.md`):
 *   1. Atomic — all ops succeed or none do.
 *   2. One round-trip.
 *   3. Validation up-front (per-entity schemas in CRUD service).
 *   4. Collision rejection (see `detectBulkCollisions`).
 *
 * @example
 * import * as v from 'valibot';
 * import { BulkRequestSchema } from '@donotdev/schemas';
 *
 * const body = v.parse(BulkRequestSchema, {
 *   inserts: [{ name: 'Alice' }],
 *   updates: [{ id: 'a', patch: { name: 'Bob' } }],
 *   deletes: ['c'],
 * });
 */
declare const BulkRequestSchema: v.ObjectSchema<{
    readonly inserts: v.OptionalSchema<v.ArraySchema<v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>, undefined>, undefined>;
    readonly updates: v.OptionalSchema<v.ArraySchema<v.ObjectSchema<{
        readonly id: v.StringSchema<undefined>;
        readonly patch: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
    }, undefined>, undefined>, undefined>;
    readonly deletes: v.OptionalSchema<v.ArraySchema<v.StringSchema<undefined>, undefined>, undefined>;
}, undefined>;
/**
 * Wire schema for `POST /:collection/bulk` response body.
 *
 * Arrays preserve input order so consumers can zip the echoed ids back onto
 * the client-side op list (e.g. to reconcile optimistic cache entries).
 *
 * @example
 * import * as v from 'valibot';
 * import { BulkResponseSchema } from '@donotdev/schemas';
 *
 * const result = v.parse(BulkResponseSchema, {
 *   insertedIds: ['new-1'],
 *   updatedIds: ['a'],
 *   deletedIds: ['c'],
 * });
 */
declare const BulkResponseSchema: v.ObjectSchema<{
    readonly insertedIds: v.ArraySchema<v.StringSchema<undefined>, undefined>;
    readonly updatedIds: v.ArraySchema<v.StringSchema<undefined>, undefined>;
    readonly deletedIds: v.ArraySchema<v.StringSchema<undefined>, undefined>;
}, undefined>;
/**
 * Inferred request type for the bulk endpoint.
 *
 * @example
 * import type { BulkRequest } from '@donotdev/schemas';
 *
 * const req: BulkRequest = { deletes: ['a'] };
 */
type BulkRequest = v.InferOutput<typeof BulkRequestSchema>;
/**
 * Inferred response type for the bulk endpoint.
 *
 * @example
 * import type { BulkResponse } from '@donotdev/schemas';
 *
 * const res: BulkResponse = { insertedIds: [], updatedIds: [], deletedIds: [] };
 */
type BulkResponse = v.InferOutput<typeof BulkResponseSchema>;
/**
 * Report returned by {@link detectBulkCollisions}.
 *
 * `where` identifies the first category of collision encountered. `collisions`
 * lists the offending ids for that category. Callers decide how to surface
 * this (the CRUD service throws; server handlers return 400).
 *
 * @since 0.2.0
 */
interface BulkCollisionReport {
    /** Ids that appear in both collided sets. Empty iff `where === null`. */
    collisions: string[];
    /** Which pair collided, or `null` when no collision was found. */
    where: 'updates-deletes' | 'inserts-updates' | null;
}
/**
 * Detects id collisions that must reject a bulk op before any write.
 *
 * Separated from the Valibot parse so the wire schema stays purely structural
 * and callers can surface a precise error (which ids, which pair). Pure, no
 * side effects — the caller throws.
 *
 * Collision rules (see `BULK_CRUD_TODO.md` §7):
 *   - Same id in `updates` and `deletes` → ambiguous intent, reject.
 *   - Same id in `inserts` (if the client supplies an explicit `id`) and
 *     `updates` → ambiguous intent, reject.
 *   - Inserts without an explicit id never collide (server mints the id).
 *
 * Checks run in order: `updates-deletes` first, then `inserts-updates`. The
 * first collision found short-circuits — one clear error per request.
 *
 * @param ops - The bulk ops to inspect. All three arrays are optional.
 * @returns A report; `where === null` means no collision.
 *
 * @example
 * import { detectBulkCollisions } from '@donotdev/schemas';
 *
 * detectBulkCollisions({ updates: [{ id: 'a', patch: {} }], deletes: ['a'] });
 * // => { collisions: ['a'], where: 'updates-deletes' }
 */
declare function detectBulkCollisions(ops: {
    inserts?: Array<{
        id?: string;
        [k: string]: unknown;
    }>;
    updates?: Array<{
        id: string;
        patch: unknown;
    }>;
    deletes?: string[];
}): BulkCollisionReport;

/**
 * @fileoverview Canvas base schemas + catalog + validators
 * @description Valibot schemas for the two canvas contracts (agent -> canvas
 *   render, canvas -> agent event), plus the process-local widget registry
 *   and the two validation entry points (`validateBlock`, `validateEvent`).
 *
 *   The catalog is the single trust boundary between untrusted
 *   LLM-originated payloads and the renderer. Unknown kinds, missing
 *   actions, and schema mismatches are all reported as `{ ok: false }`;
 *   callers never receive malformed data.
 *
 *   This file is isomorphic (no React). The React host + component
 *   registration helpers live in `@donotdev/canvas`.
 *
 * @version 0.1.0
 * @since 0.1.0
 * @author AMBROISE PARK Consulting
 */

/**
 * Box-proxied image URL. Covers, avatars, thumbnails — every image in a
 * canvas widget MUST resolve through the box proxy.
 *
 * Accepted forms:
 * - `/proxy/...` — absolute proxy path on the same origin.
 * - `data:image/...` — inline data URI (agent-generated thumbnails).
 */
declare const ProxiedImageUrlSchema: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.CheckAction<string, "Image URL must be box-proxied (/proxy/...) or an inline data:image URI.">]>;
declare const CanvasLifetimeSchema: v.PicklistSchema<["ephemeral", "session", "persistent"], undefined>;
declare const CanvasWidgetMetadataSchema: v.ObjectSchema<{
    readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
    readonly pinnable: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
    readonly preferredHeight: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
}, undefined>;
declare const CanvasBlockSchema: v.ObjectSchema<{
    readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    readonly kind: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    readonly lifetime: v.OptionalSchema<v.PicklistSchema<["ephemeral", "session", "persistent"], undefined>, "ephemeral">;
    readonly metadata: v.OptionalSchema<v.ObjectSchema<{
        readonly title: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
        readonly pinnable: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
        readonly preferredHeight: v.OptionalSchema<v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.MinValueAction<number, 0, undefined>]>, undefined>;
    }, undefined>, undefined>;
    readonly payload: v.UnknownSchema;
}, undefined>;
declare const CanvasEventSchema: v.ObjectSchema<{
    readonly widgetId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    readonly action: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.MinLengthAction<string, 1, undefined>]>;
    readonly payload: v.UnknownSchema;
}, undefined>;
/**
 * A widget as it lives in the registry. Widened to accept an arbitrary
 * component attachment so the UI package can register React components
 * without this module importing React.
 */
interface RegisteredWidgetBase<Kind extends string = string, PayloadSchema extends AnyValibotSchema = AnyValibotSchema, Actions extends Record<string, AnyValibotSchema> = Record<string, AnyValibotSchema>> extends WidgetDef<Kind, PayloadSchema, Actions> {
    readonly component: unknown;
}
declare function registerWidget(widget: RegisteredWidgetBase): void;
declare function getWidget(kind: string): RegisteredWidgetBase | undefined;
declare function listWidgets(): readonly RegisteredWidgetBase[];
type ValidateResult<T> = {
    readonly ok: true;
    readonly value: T;
    readonly widget: RegisteredWidgetBase;
} | {
    readonly ok: false;
    readonly reason: string;
};
/**
 * Validate an incoming canvas block end-to-end: envelope shape, kind is
 * in the allowlist, payload conforms to the widget's payload schema, and
 * (optionally) the widget's surface is reachable by the caller's access tier.
 *
 * Failure ordering: envelope → kind → payload → surface. Surface-rejection
 * reasons are prefixed `surface_forbidden: ` so callers can distinguish
 * policy rejection from schema rejection.
 */
declare function validateBlock(block: unknown, opts?: ValidateBlockOptions): ValidateResult<CanvasBlock>;
declare function validateEvent(event: unknown, widgetKind: string): ValidateResult<CanvasEvent>;

export { AGGREGATE_FILTER_OPERATORS, AGGREGATE_OPERATIONS, AIChatRequestSchema, AIChatResponseSchema, AIMessageSchema, AIProviderConfigSchema, AIToolCallSchema, AIToolDefinitionSchema, AIUsageSchema, AI_ERROR_CODES, AI_MODELS, AI_PROVIDERS, AI_ROLES, AI_TIERS, AI_TOKEN_PRICING, AUTH_EVENTS, AUTH_PARTNERS, AUTH_PARTNER_STATE, AuthHardening, AuthUserSchema, BACKEND_GENERATED_FIELD_NAMES, BILLING_EVENTS, BREAKPOINT_RANGES, BREAKPOINT_THRESHOLDS, BulkAcrossCycleError, BulkCollisionError, BulkDeleteIdSchema, BulkInsertSchema, BulkNotImplementedError, BulkRequestSchema, BulkResponseSchema, BulkUpdateSchema, COMMON_TIER_CONFIGS, CONFIDENCE_LEVELS, CONSENT_CATEGORY, CONTEXTS, CRUD_OPERATORS, CURRENCY_MAP, CanvasBlockSchema, CanvasEventSchema, CanvasLifetimeSchema, CanvasWidgetMetadataSchema, CheckoutSessionMetadataSchema, ConditionBuilder, CreateCheckoutSessionRequestSchema, CreateCheckoutSessionResponseSchema, CustomClaimsSchema, DEFAULT_AI_CONFIG, DEFAULT_AI_MARKUP, DEFAULT_CRUD_TIMEOUT, DEFAULT_ENTITY_ACCESS, DEFAULT_ERROR_MESSAGES, DEFAULT_LAYOUT_PRESET, DEFAULT_STATUS_OPTIONS, DEFAULT_STATUS_VALUE, DEFAULT_SUBSCRIPTION, DEFAULT_UPLOAD_TIMEOUT, DENSITY, DoNotDevError, EDITABLE, EMAIL_ERROR_CODES, EMAIL_PROVIDERS, EMAIL_VERIFICATION_STATUS, ENTITY_HOOK_ERRORS, ENVIRONMENTS, ERROR_CODES, ERROR_SEVERITY, ERROR_SOURCE, EntityHookError, FEATURES, FEATURE_CONSENT_MATRIX, FEATURE_STATUS, FIELD_TYPES, FIREBASE_ERROR_MAP, FOOTER_MODE, GITHUB_PERMISSION_LEVELS, HIDDEN_STATUSES, LAYOUT_PRESET, LIST_SCHEMA_TYPE, OAUTH_EVENTS, OAUTH_PARTNERS, ORDER_DIRECTION, PARTNER_ICONS, PAYLOAD_EVENTS, PERMISSIONS, PLATFORMS, PWA_ASSET_TYPES, PWA_DISPLAY_MODES, ProductDeclarationSchema, ProductDeclarationsSchema, ProxiedImageUrlSchema, ROUTE_SOURCES, STORAGE_SCOPES, STORAGE_TYPES, STRIPE_EVENTS, STRIPE_MODES, SUBSCRIPTION_DURATIONS, SUBSCRIPTION_STATUS, SUBSCRIPTION_TIERS, SendEmailRequestSchema, SendEmailResponseSchema, index_d as ServerUtils, SingletonManager, StripeBackConfigSchema, StripeFrontConfigSchema, StripePaymentSchema, StripeSubscriptionSchema, SubscriptionClaimsSchema, SubscriptionDataSchema, TECHNICAL_FIELD_NAMES, USER_ROLES, UserSubscriptionSchema, VISIBILITY, WebhookEventSchema, addMonths, addYears, addressSchema, arraySchema, baseFields, booleanSchema, calculateSubscriptionEndDate, captureErrorToSentry, checkGitHubAccessSchema, clearGlobalSingleton, clearSchemaGenerators, clearScopeProviders, commonErrorCodeMappings, compactToISOString, configureProviders, createAsyncSingleton, createDefaultSubscriptionClaims, createDefaultUserProfile, createEntitySchema, createErrorHandler, createMetadata, createMethodProxy, createSchemas, createSingleton, createSingletonWithParams, dateSchema, defineEntity, deleteEntitySchema, detectBulkCollisions, detectErrorSource, disconnectOAuthSchema, emailSchema, enhanceSchema, ensureSpreadable, evaluateCondition, evaluateFieldConditions, exchangeTokenSchema, fileSchema, filesSchema, filterVisibleFields, formatCurrency, formatDate, formatRelativeTime, gdprConsentSchema, generateCodeChallenge, generateCodeVerifier, generateFirestoreRuleCondition, generatePKCEPair, generateUUID, geopointSchema, getBreakpointFromWidth, getBreakpointUtils, getCollectionName, getConditionDependencies, getConnectionsSchema, getCurrencyLocale, getCurrencySymbol, getCurrentTimestamp, getEntitySchema, getGlobalSingleton, getListCardFieldNames, getProvider, getRegisteredSchemaTypes, getRegisteredScopeProviders, getRoleFromClaims, getSchemaType, getScopeValue, getVisibleFields, getWeekFromISOString, getWidget, githubPermissionSchema, githubRepoConfigSchema, grantGitHubAccessSchema, handleError, hasCustomSchemaGenerator, hasMetadata, hasProvider, hasRestrictedVisibility, hasRoleAccess, hasScopeProvider, hasTierAccess, ibanSchema, isAuthPartnerId, isBackendGeneratedField, isBreakpoint, isCompactDateString, isFieldVisible, isFrameworkField, isOAuthPartnerId, isPKCESupported, isoToCompactString, lazyImport, listEntitiesSchema, listWidgets, mapSchema, mapToDoNotDevError, maybeTranslate, multiselectSchema, neverSchema, normalizeToISOString, numberSchema, overrideFeatures, overridePaymentModes, overridePermissions, overrideSubscriptionStatus, overrideSubscriptionTiers, overrideUserRoles, parseDate, parseDateToNoonUTC, parseISODate, parseServerCookie, passwordSchema, pictureSchema, picturesSchema, priceSchema, rangeOptions, referenceSchema, refreshTokenSchema, registerSchemaGenerator, registerScopeProvider, registerUniqueConstraintValidator, registerWidget, resetProviders, revokeGitHubAccessSchema, safeValidate, sanitizeHref, selectSchema, showNotification, stringSchema, switchSchema, telSchema, textSchema, timestampToISOString, toDateOnly, toISOString, translateArray, translateArrayRange, translateArrayWithIndices, translateObjectArray, unregisterScopeProvider, updateEntitySchema, updateMetadata, urlSchema, validateAIChatRequest, validateAIChatResponse, validateAuthPartners, validateAuthSchemas, validateAuthUser, validateBillingSchemas, validateBlock, validateCheckoutSessionMetadata, validateCodeChallenge, validateCodeVerifier, validateCreateCheckoutSessionRequest, validateCreateCheckoutSessionResponse, validateCustomClaims, validateDates, validateDocument, validateEnvVar, validateEvent, validateMetadata, validateOAuthPartners, validateSendEmailRequest, validateSendEmailResponse, validateStripeBackConfig, validateStripeFrontConfig, validateSubscriptionClaims, validateSubscriptionData, validateUniqueFields, validateUrl, validateUserSubscription, validateWebhookEvent, validateWithSchema, when, withErrorHandling, withGracefulDegradation, withTimeout, wrapAuthError, wrapCrudError, wrapStorageError };
export type { AIAPI, AIChatRequest, AIChatResponse, AIConfig, AICostConfig, AICostEvent, AICostRecord, AICostResult, AIErrorCode, AIMessage, AIModelPricing, AIProvider, AIProviderConfig, AIRateLimitConfig, AIRouteConfig, AITierId, AIToolCall, AIToolDefinition, AIToolParameter, AIUsage, AccountLinkResult, AccountLinkingInfo, AdminCheckHookResult, AdminClaims, AggregateConfig, AggregateFilterOperator, AggregateOperation, AggregateRequest, AggregateResponse, AnyEntity, AnyFieldValue, AnyValibotSchema, ApiResponse, AppConfig, AppCookieCategories, AppMetadata, AppProvidersProps, AssetsPluginConfig, AttemptRecord, AuditEvent, AuditEventType, AuthAPI, AuthActions, AuthConfig, AuthContextValue, AuthCoreHookResult, AuthError, AuthEventData, AuthEventKey, AuthEventName, AuthHardeningConfig, AuthHardeningContext, AuthMethod, AuthPartner, AuthPartnerHookResult, AuthPartnerId, AuthPartnerResult, AuthPartnerState, AuthProvider, AuthProviderProps, AuthRedirectHookResult, AuthRedirectOperation, AuthRedirectOptions, AuthResult, AuthState, AuthStateStore, AuthStatus, AuthTokenHookResult, AuthUser, BackendGeneratedField, BaseActions, BaseCredentials, BaseDocument, BaseEntityFields, BasePartnerState, BaseState, BaseStoreActions, BaseStoreState, BaseUserProfile, BasicUserInfo, BeforeCheckoutHook, BeforeCheckoutResult, BillingAPI, BillingAdapter, BillingErrorCode, BillingEvent, BillingEventData, BillingEventKey, BillingEventName, BillingProvider, BillingProviderConfig, BillingRedirectOperation, Breakpoint, BreakpointUtils, BuiltInFieldType, BulkAcrossBatch, BulkAcrossResult, BulkCollisionReport, BulkOperations, BulkRequest, BulkResponse, BulkResult, BusinessEntity, CachedError, CanAPI, CanvasBlock, CanvasCallerAccess, CanvasEvent, CanvasLifetime, CanvasSurface, CanvasWidgetMetadata, CanvasWidgetProps, CheckGitHubAccessRequest, CheckoutMode, CheckoutOptions, CheckoutSessionMetadata, CollectionSubscriptionCallback, ColumnDef, CommonSubscriptionFeatures, CommonTranslations, ConditionBuilderLike, ConditionExpression, ConditionGroup, ConditionInput, ConditionNode, ConditionOperator, ConditionResult, ConditionalBehavior, ConfidenceLevel, ConnectOptions, ConsentAPI, ConsentActions, ConsentCategory, ConsentState, Context, CookieOptions, CreateCheckoutSessionRequest, CreateCheckoutSessionResponse, CreateEntityData, CreateEntityRequest, CreateEntityResponse, CrudAPI, CrudCardProps, CrudConfig, CrudCreateInput, CrudDocQuery, CrudListQuery, CrudOperationOptions, CrudOperator, CurrencyEntry, CustomClaims, CustomFieldOptionsMap, CustomSchemaGenerator, CustomStoreConfig, DateFormatOptions, DateFormatPreset, DateValue, DeleteEntityRequest, DeleteEntityResponse, Density, DnDevOverride, DnDevWrapper, DndevFrameworkConfig, DndevProviders, DndevStoreApi, DoNotDevCookieCategories, DocumentSubscriptionCallback, DynamicFormRule, Editable, EffectiveConnectionType, EmailConfig, EmailErrorCode, EmailProvider, EmailRouteConfig, EmailTemplate, EmailTemplateRegistry, EmailVerificationHookResult, EmailVerificationStatus, Entity, EntityAccessConfig, EntityAccessDefaults, EntityBrowseBaseProps, EntityCardListProps, EntityDisplayRendererProps, EntityField, EntityFieldMapDefault, EntityFormRendererProps, EntityHookErrors, EntityListProps, EntityMetadata, EntityOwnershipConfig, EntityOwnershipPublicCondition, EntityRecommendationsProps, EntityRecord, EntityRowFromFields, EntityTemplateProps, EntityTranslations, EnvironmentMode, ErrorCode, ErrorHandlerConfig, ErrorHandlerFunction, ErrorSeverity, ErrorSource, ExchangeTokenParams, ExchangeTokenRequest, ExchangeTokenResponse, FaviconConfig, Feature, FeatureAccessHookResult, FeatureConsentRequirement, FeatureHookResult, FeatureId, FeatureName, FeatureStatus, FeaturesConfig, FeaturesPluginConfig, FeaturesRequiringAnyConsent, FeaturesRequiringConsent, FeaturesWithoutConsent, FieldCondition, FieldType, FieldTypeToValue, FileAsset, FilterVisibleFieldsOptions, FirebaseCallOptions, FirebaseConfig, FirestoreTimestamp, FirestoreUniqueConstraintValidator, FooterConfig, FooterMode, FooterZoneConfig, FormConfig, FormStep, FunctionCallConfig, FunctionCallContext, FunctionCallOptions, FunctionCallResult, FunctionClient, FunctionClientFactoryOptions, FunctionDefaults, FunctionEndpoint, FunctionError, FunctionLoader, FunctionMemory, FunctionMeta, FunctionPlatform, FunctionResponse, FunctionSchema, FunctionSchemas, FunctionSystem, FunctionTrigger, FunctionsConfig, GetCustomClaimsResponse, GetEntityData, GetEntityRequest, GetEntityResponse, GetUserAuthStatusResponse, GetVisibleFieldsOptions, GitHubPermission, GitHubRepoConfig, GrantGitHubAccessRequest, GroupByDefinition, HandleErrorOptions, HeaderZoneConfig, I18nConfig, I18nPluginConfig, I18nProviderProps, ICallableProvider, ICrudAdapter, ID, INetworkManager, IServerAuthAdapter, IStorageAdapter, IStorageManager, IStorageStrategy, InferEntityRow, Invoice, InvoiceItem, LanguageData, LanguageInfo, LayoutConfig, LayoutPreset, LegalCompanyInfo, LegalConfig, LegalContactInfo, LegalDirectorInfo, LegalHostingInfo, LegalJurisdictionInfo, LegalSectionsConfig, LegalWebsiteInfo, ListCardLayout, ListEntitiesRequest, ListEntitiesResponse, ListEntityData, ListOptions, ListResponse, ListSchemaType, LoadingActions, LoadingState, LockoutResult, MergedBarConfig, MergedEntityFieldMap, MetricDefinition, MobileBehaviorConfig, ModalActions, ModalState, MutableMergedEntityFieldMap, MutationResponse, NavigationRoute, NetworkCheckConfig, NetworkConnectionType, NetworkReconnectCallback, NetworkState, NetworkStatus, NetworkStatusHookResult, OAuthAPI, OAuthApiRequestOptions, OAuthCallbackHookResult, OAuthConnection, OAuthConnectionInfo, OAuthConnectionRequest, OAuthConnectionStatus, OAuthCredentials, OAuthEventData, OAuthEventKey, OAuthEventName, OAuthPartner, OAuthPartnerHookResult, OAuthPartnerId, OAuthPartnerResult, OAuthPartnerState, OAuthPurpose, OAuthRedirectOperation, OAuthRefreshRequest, OAuthRefreshResponse, OAuthResult, OAuthStoreActions, OAuthStoreState, Observable, OperationSchemas, OrderByClause, OrderDirection, PWAAssetType, PWADisplayMode, PWAPluginConfig, PageAuth, PageMeta, PaginatedQueryResult, PaginationOptions, PartnerConnectionState, PartnerIconId, PartnerId, PartnerResult, PartnerType, PayloadCacheEventData, PayloadDocument, PayloadDocumentEventData, PayloadEventKey, PayloadEventName, PayloadGlobalEventData, PayloadMediaEventData, PayloadPageRegenerationEventData, PayloadRequest, PayloadUserEventData, PaymentEventData, PaymentMethod, PaymentMethodType, PaymentMode, Permission, Picture, Platform, PresetConfig, PresetRegistry, ProcessPaymentSuccessRequest, ProcessPaymentSuccessResponse, ProductDeclaration, ProviderInstances, QueryConfig, QueryOptions, QueryOrderBy, QueryWhereClause, RateLimitBackend, RateLimitConfig, RateLimitManager, RateLimitResult, RateLimitState, RateLimiter, ReadCallback, RedirectOperation, RedirectOverlayActions, RedirectOverlayConfig, RedirectOverlayPhase, RedirectOverlayState, Reference, RefreshSubscriptionRequest, RefreshSubscriptionResponse, RegisteredWidgetBase, RemoveCustomClaimsResponse, ResolvedLayoutConfig, RevokeGitHubAccessRequest, RouteMeta, RouteSource, RoutesPluginConfig, SEOConfig, SchemaMetadata, SchemaWithVisibility, ScopeConfig, ScopeProviderFn, SecurityContext, SecurityEntityConfig, SelectOption, SendEmailRequest, SendEmailResponse, SeoMeta, ServerRateLimitConfig, ServerRateLimitResult, ServerUserRecord, SetCustomClaimsResponse, SidebarZoneConfig, SignUpMetadata, SlotContent, StatusField, StorageOptions, StorageScope, StorageType, Store, StripeBackConfig, StripeCheckoutRequest, StripeCheckoutResponse, StripeCheckoutSessionEventData, StripeConfig, StripeCustomer, StripeCustomerEventData, StripeEventData, StripeEventKey, StripeEventName, StripeFrontConfig, StripeInvoice, StripeInvoiceEventData, StripePayment, StripePaymentIntentEventData, StripePaymentMethod, StripePrice, StripeProduct, StripeProvider, StripeSubscription, StripeSubscriptionData, StripeWebhookEvent, StripeWebhookEventData, Subscription, SubscriptionClaims, SubscriptionConfig, SubscriptionData, SubscriptionDuration, SubscriptionEventData, SubscriptionHookResult, SubscriptionInfo, SubscriptionStatus, SubscriptionTier, SupportedLanguage, TechnicalField, ThemeActions, ThemeInfo, ThemeMode, ThemeState, ThemesPluginConfig, TierAccessHookResult, Timestamp, TokenInfo, TokenResponse, TokenState, TokenStatus, TranslationOptions, TranslationResource, TypedBaseFields, UIFieldOptions, UniqueConstraintValidator, UniqueKeyDefinition, UnsubscribeFn, UpdateEntityData, UpdateEntityRequest, UpdateEntityResponse, UploadOptions, UploadProgressCallback, UploadResult, UseFunctionsCallResult, UseFunctionsMutationOptions, UseFunctionsMutationResult, UseFunctionsQueryOptions, UseFunctionsQueryResult, UseTranslationOptionsEnhanced, UserContext, UserProfile, UserProviderData, UserRole, UserSubscription, ValidateBlockOptions, ValidateResult, ValidationRules, ValueTypeForField, VerifiedToken, Visibility, WebhookEvent, WebhookEventData, WhereClause, WhereOperator, WidgetDef, WithMetadata, dndevSchema };
