@frank-auth/react
Version:
Flexible and customizable React UI components for Frank Authentication
1 lines • 36.4 kB
Source Map (JSON)
{"version":3,"file":"validators.cjs","sources":["../../../src/config/validators.ts"],"sourcesContent":["/**\n * @frank-auth/react - Configuration Validators\n *\n * Comprehensive validation system for all configuration types with\n * detailed error reporting and type safety.\n */\n\nimport type {\n\tAppearanceConfig,\n\tAppearanceMode,\n\tColorVariant,\n\tComponentOverrides,\n\tComponentSize,\n\tConfigValidationError,\n\tConfigValidationResult,\n\tFrankAuthUIConfig,\n\tLocale,\n\tLocalizationConfig,\n\tOrganizationConfig,\n\tTheme,\n\tThemeMode,\n\tUserType,\n} from \"./types\";\n\n// ============================================================================\n// Validation Utilities\n// ============================================================================\n\n/**\n * Creates a validation error\n */\nfunction createError(\n\tpath: string,\n\tmessage: string,\n\tvalue?: any,\n): ConfigValidationError {\n\treturn { path, message, value };\n}\n\n/**\n * Creates a validation warning\n */\nfunction createWarning(\n\tpath: string,\n\tmessage: string,\n\tvalue?: any,\n): ConfigValidationError {\n\treturn { path, message, value };\n}\n\n/**\n * Validates if a value is a valid URL\n */\nfunction isValidUrl(url: string): boolean {\n\ttry {\n\t\tnew URL(url);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Validates if a value is a valid hex color\n */\nfunction isValidHexColor(color: string): boolean {\n\treturn /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);\n}\n\n/**\n * Validates if a value is a valid CSS value\n */\nfunction isValidCSSValue(value: string): boolean {\n\t// Basic CSS value validation - can be extended\n\treturn typeof value === \"string\" && value.length > 0;\n}\n\n/**\n * Validates if a value is one of the allowed options\n */\nfunction isValidOption<T extends string>(\n\tvalue: string,\n\toptions: readonly T[],\n): value is T {\n\treturn options.includes(value as T);\n}\n\n/**\n * Validates if an object has required properties\n */\nfunction hasRequiredProperties(obj: any, properties: string[]): boolean {\n\treturn properties.every((prop) => prop in obj && obj[prop] !== undefined);\n}\n\n// ============================================================================\n// Specific Validators\n// ============================================================================\n\n/**\n * Validates publishable key format\n */\nexport function validatePublishableKey(key: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!key) {\n\t\terrors.push(createError(\"publishableKey\", \"Publishable key is required\"));\n\t\treturn errors;\n\t}\n\n\tif (typeof key !== \"string\") {\n\t\terrors.push(\n\t\t\tcreateError(\"publishableKey\", \"Publishable key must be a string\", key),\n\t\t);\n\t\treturn errors;\n\t}\n\n\t// Check format: pk_test_... or pk_live_...\n\tif (!/^pk_(test|live|standalone)_[a-zA-Z0-9_]+$/.test(key)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"publishableKey\",\n\t\t\t\t\"Invalid publishable key format. Expected: pk_test_... or pk_live_...\",\n\t\t\t\tkey,\n\t\t\t),\n\t\t);\n\t}\n\n\tif (key.length < 20) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"publishableKey\",\n\t\t\t\t\"Publishable key appears to be too short\",\n\t\t\t\tkey,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates API URL\n */\nexport function validateApiUrl(url?: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!url) {\n\t\treturn errors; // API URL is optional\n\t}\n\n\tif (typeof url !== \"string\") {\n\t\terrors.push(createError(\"apiUrl\", \"API URL must be a string\", url));\n\t\treturn errors;\n\t}\n\n\tif (!isValidUrl(url)) {\n\t\terrors.push(createError(\"apiUrl\", \"Invalid API URL format\", url));\n\t}\n\n\t// Check for HTTPS in production\n\tif (\n\t\turl.startsWith(\"http://\") &&\n\t\t!url.includes(\"localhost\") &&\n\t\t!url.includes(\"127.0.0.1\")\n\t) {\n\t\terrors.push(\n\t\t\tcreateWarning(\n\t\t\t\t\"apiUrl\",\n\t\t\t\t\"Consider using HTTPS for production API URL\",\n\t\t\t\turl,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates user type\n */\nexport function validateUserType(userType: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\tconst validUserTypes: UserType[] = [\"internal\", \"external\", \"end_user\"];\n\n\tif (!isValidOption(userType, validUserTypes)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"userType\",\n\t\t\t\t`Invalid user type. Must be one of: ${validUserTypes.join(\", \")}`,\n\t\t\t\tuserType,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates locale\n */\nexport function validateLocale(locale: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\tconst validLocales: Locale[] = [\n\t\t\"en\",\n\t\t\"es\",\n\t\t\"fr\",\n\t\t\"de\",\n\t\t\"pt\",\n\t\t\"it\",\n\t\t\"ja\",\n\t\t\"ko\",\n\t\t\"zh\",\n\t];\n\n\tif (!isValidOption(locale, validLocales)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"locale\",\n\t\t\t\t`Invalid locale. Must be one of: ${validLocales.join(\", \")}`,\n\t\t\t\tlocale,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n// ============================================================================\n// Theme Validation\n// ============================================================================\n\n/**\n * Validates theme mode\n */\nexport function validateThemeMode(mode: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\tconst validModes: ThemeMode[] = [\"light\", \"dark\", \"system\"];\n\n\tif (!isValidOption(mode, validModes)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"theme.mode\",\n\t\t\t\t`Invalid theme mode. Must be one of: ${validModes.join(\", \")}`,\n\t\t\t\tmode,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates color palette\n */\nexport function validateColorPalette(\n\tcolors: any,\n\tpath = \"theme.colors\",\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!colors || typeof colors !== \"object\") {\n\t\terrors.push(createError(path, \"Colors must be an object\", colors));\n\t\treturn errors;\n\t}\n\n\t// Validate required color properties\n\tconst requiredColors = [\"primary\", \"secondary\", \"background\", \"foreground\"];\n\tfor (const colorKey of requiredColors) {\n\t\tif (!(colorKey in colors)) {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`${path}.${colorKey}`,\n\t\t\t\t\t`Missing required color: ${colorKey}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst colorValue = colors[colorKey];\n\n\t\t// Primary and secondary should be objects with shades\n\t\tif (colorKey === \"primary\" || colorKey === \"secondary\") {\n\t\t\tif (typeof colorValue !== \"object\") {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateError(\n\t\t\t\t\t\t`${path}.${colorKey}`,\n\t\t\t\t\t\t`${colorKey} must be an object with color shades`,\n\t\t\t\t\t\tcolorValue,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Check for required shades\n\t\t\tconst requiredShades = [\"DEFAULT\", \"foreground\"];\n\t\t\tfor (const shade of requiredShades) {\n\t\t\t\tif (!(shade in colorValue)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tcreateError(\n\t\t\t\t\t\t\t`${path}.${colorKey}.${shade}`,\n\t\t\t\t\t\t\t`Missing required shade: ${shade}`,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t} else if (!isValidHexColor(colorValue[shade])) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tcreateError(\n\t\t\t\t\t\t\t`${path}.${colorKey}.${shade}`,\n\t\t\t\t\t\t\t\"Invalid hex color format\",\n\t\t\t\t\t\t\tcolorValue[shade],\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Background, foreground should be hex colors\n\t\t\tif (!isValidHexColor(colorValue)) {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateError(\n\t\t\t\t\t\t`${path}.${colorKey}`,\n\t\t\t\t\t\t\"Invalid hex color format\",\n\t\t\t\t\t\tcolorValue,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates typography configuration\n */\nexport function validateTypography(\n\ttypography: any,\n\tpath = \"theme.typography\",\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!typography || typeof typography !== \"object\") {\n\t\terrors.push(createError(path, \"Typography must be an object\", typography));\n\t\treturn errors;\n\t}\n\n\t// Validate font families\n\tif (typography.fontFamily) {\n\t\tif (typeof typography.fontFamily !== \"object\") {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`${path}.fontFamily`,\n\t\t\t\t\t\"Font family must be an object\",\n\t\t\t\t\ttypography.fontFamily,\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tif (\n\t\t\t\ttypography.fontFamily.sans &&\n\t\t\t\t!Array.isArray(typography.fontFamily.sans)\n\t\t\t) {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateError(\n\t\t\t\t\t\t`${path}.fontFamily.sans`,\n\t\t\t\t\t\t\"Sans font family must be an array\",\n\t\t\t\t\t\ttypography.fontFamily.sans,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\ttypography.fontFamily.mono &&\n\t\t\t\t!Array.isArray(typography.fontFamily.mono)\n\t\t\t) {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateError(\n\t\t\t\t\t\t`${path}.fontFamily.mono`,\n\t\t\t\t\t\t\"Mono font family must be an array\",\n\t\t\t\t\t\ttypography.fontFamily.mono,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Validate font sizes\n\tif (typography.fontSize) {\n\t\tif (typeof typography.fontSize !== \"object\") {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`${path}.fontSize`,\n\t\t\t\t\t\"Font size must be an object\",\n\t\t\t\t\ttypography.fontSize,\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tObject.entries(typography.fontSize).forEach(([size, value]) => {\n\t\t\t\tif (!Array.isArray(value) || value.length !== 2) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tcreateError(\n\t\t\t\t\t\t\t`${path}.fontSize.${size}`,\n\t\t\t\t\t\t\t\"Font size value must be an array with [size, lineHeight]\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates complete theme configuration\n */\nexport function validateThemeConfig(\n\ttheme: Partial<Theme>,\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!theme || typeof theme !== \"object\") {\n\t\terrors.push(createError(\"theme\", \"Theme must be an object\", theme));\n\t\treturn errors;\n\t}\n\n\t// Validate theme mode\n\tif (theme.mode) {\n\t\terrors.push(...validateThemeMode(theme.mode));\n\t}\n\n\t// Validate colors\n\tif (theme.colors) {\n\t\terrors.push(...validateColorPalette(theme.colors));\n\t}\n\n\t// Validate typography\n\tif (theme.typography) {\n\t\terrors.push(...validateTypography(theme.typography));\n\t}\n\n\t// Validate spacing\n\tif (theme.spacing) {\n\t\tif (typeof theme.spacing !== \"object\") {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t\"theme.spacing\",\n\t\t\t\t\t\"Spacing must be an object\",\n\t\t\t\t\ttheme.spacing,\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tObject.entries(theme.spacing).forEach(([key, value]) => {\n\t\t\t\tif (!isValidCSSValue(value as string)) {\n\t\t\t\t\terrors.push(\n\t\t\t\t\t\tcreateError(\n\t\t\t\t\t\t\t`theme.spacing.${key}`,\n\t\t\t\t\t\t\t\"Invalid CSS value for spacing\",\n\t\t\t\t\t\t\tvalue,\n\t\t\t\t\t\t),\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n// ============================================================================\n// Appearance Validation\n// ============================================================================\n\n/**\n * Validates appearance mode\n */\nexport function validateAppearanceMode(mode: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\tconst validModes: AppearanceMode[] = [\"system\", \"light\", \"dark\"];\n\n\tif (!isValidOption(mode, validModes)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"appearance.mode\",\n\t\t\t\t`Invalid appearance mode. Must be one of: ${validModes.join(\", \")}`,\n\t\t\t\tmode,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates component size\n */\nexport function validateComponentSize(size: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\tconst validSizes: ComponentSize[] = [\"sm\", \"md\", \"lg\"];\n\n\tif (!isValidOption(size, validSizes)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"size\",\n\t\t\t\t`Invalid component size. Must be one of: ${validSizes.join(\", \")}`,\n\t\t\t\tsize,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates color variant\n */\nexport function validateColorVariant(variant: string): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\tconst validVariants: ColorVariant[] = [\n\t\t\"default\",\n\t\t\"primary\",\n\t\t\"secondary\",\n\t\t\"success\",\n\t\t\"warning\",\n\t\t\"danger\",\n\t];\n\n\tif (!isValidOption(variant, validVariants)) {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"color\",\n\t\t\t\t`Invalid color variant. Must be one of: ${validVariants.join(\", \")}`,\n\t\t\t\tvariant,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates branding configuration\n */\nexport function validateBrandingConfig(\n\tbranding: any,\n\tpath = \"appearance.branding\",\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!branding || typeof branding !== \"object\") {\n\t\terrors.push(createError(path, \"Branding must be an object\", branding));\n\t\treturn errors;\n\t}\n\n\t// Validate logo\n\tif (branding.logo) {\n\t\tif (branding.logo.url && !isValidUrl(branding.logo.url)) {\n\t\t\terrors.push(\n\t\t\t\tcreateError(`${path}.logo.url`, \"Invalid logo URL\", branding.logo.url),\n\t\t\t);\n\t\t}\n\t\tif (!branding.logo.alt) {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`${path}.logo.alt`,\n\t\t\t\t\t\"Logo alt text is required for accessibility\",\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\t// Validate colors\n\tif (branding.colors) {\n\t\tif (branding.colors.primary && !isValidHexColor(branding.colors.primary)) {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`${path}.colors.primary`,\n\t\t\t\t\t\"Invalid hex color format\",\n\t\t\t\t\tbranding.colors.primary,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tif (\n\t\t\tbranding.colors.secondary &&\n\t\t\t!isValidHexColor(branding.colors.secondary)\n\t\t) {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`${path}.colors.secondary`,\n\t\t\t\t\t\"Invalid hex color format\",\n\t\t\t\t\tbranding.colors.secondary,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n/**\n * Validates appearance configuration\n */\nexport function validateAppearanceConfig(\n\tappearance: Partial<AppearanceConfig>,\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!appearance || typeof appearance !== \"object\") {\n\t\terrors.push(\n\t\t\tcreateError(\"appearance\", \"Appearance must be an object\", appearance),\n\t\t);\n\t\treturn errors;\n\t}\n\n\t// Validate appearance mode\n\tif (appearance.mode) {\n\t\terrors.push(...validateAppearanceMode(appearance.mode));\n\t}\n\n\t// Validate branding\n\tif (appearance.branding) {\n\t\terrors.push(...validateBrandingConfig(appearance.branding));\n\t}\n\n\t// Validate component appearance\n\tif (appearance.components) {\n\t\tconst { components } = appearance;\n\n\t\tif (components.input?.size) {\n\t\t\terrors.push(...validateComponentSize(components.input.size));\n\t\t}\n\t\tif (components.input?.color) {\n\t\t\terrors.push(...validateColorVariant(components.input.color));\n\t\t}\n\t\tif (components.button?.size) {\n\t\t\terrors.push(...validateComponentSize(components.button.size));\n\t\t}\n\t\tif (components.button?.color) {\n\t\t\terrors.push(...validateColorVariant(components.button.color));\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n// ============================================================================\n// Localization Validation\n// ============================================================================\n\n/**\n * Validates localization configuration\n */\nexport function validateLocalizationConfig(\n\tlocalization: Partial<LocalizationConfig>,\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!localization || typeof localization !== \"object\") {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"localization\",\n\t\t\t\t\"Localization must be an object\",\n\t\t\t\tlocalization,\n\t\t\t),\n\t\t);\n\t\treturn errors;\n\t}\n\n\t// Validate default locale\n\tif (localization.defaultLocale) {\n\t\terrors.push(\n\t\t\t...validateLocale(localization.defaultLocale).map((error) => ({\n\t\t\t\t...error,\n\t\t\t\tpath: `localization.${error.path}`,\n\t\t\t})),\n\t\t);\n\t}\n\n\t// Validate fallback locale\n\tif (localization.fallbackLocale) {\n\t\terrors.push(\n\t\t\t...validateLocale(localization.fallbackLocale).map((error) => ({\n\t\t\t\t...error,\n\t\t\t\tpath: `localization.${error.path}`,\n\t\t\t})),\n\t\t);\n\t}\n\n\t// Validate supported locales\n\tif (localization.supportedLocales) {\n\t\tif (!Array.isArray(localization.supportedLocales)) {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t\"localization.supportedLocales\",\n\t\t\t\t\t\"Supported locales must be an array\",\n\t\t\t\t\tlocalization.supportedLocales,\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tlocalization.supportedLocales.forEach((locale, index) => {\n\t\t\t\terrors.push(\n\t\t\t\t\t...validateLocale(locale).map((error) => ({\n\t\t\t\t\t\t...error,\n\t\t\t\t\t\tpath: `localization.supportedLocales[${index}]`,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t});\n\t\t}\n\t}\n\n\t// Validate date/time formats\n\tif (localization.dateFormat && typeof localization.dateFormat !== \"string\") {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"localization.dateFormat\",\n\t\t\t\t\"Date format must be a string\",\n\t\t\t\tlocalization.dateFormat,\n\t\t\t),\n\t\t);\n\t}\n\n\tif (localization.timeFormat && typeof localization.timeFormat !== \"string\") {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"localization.timeFormat\",\n\t\t\t\t\"Time format must be a string\",\n\t\t\t\tlocalization.timeFormat,\n\t\t\t),\n\t\t);\n\t}\n\n\treturn errors;\n}\n\n// ============================================================================\n// Organization Validation\n// ============================================================================\n\n/**\n * Validates organization configuration\n */\nexport function validateOrganizationConfig(\n\torganization: Partial<OrganizationConfig>,\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!organization || typeof organization !== \"object\") {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"organization\",\n\t\t\t\t\"Organization must be an object\",\n\t\t\t\torganization,\n\t\t\t),\n\t\t);\n\t\treturn errors;\n\t}\n\n\t// Validate organization ID\n\tif (organization.id && typeof organization.id !== \"string\") {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"organization.id\",\n\t\t\t\t\"Organization ID must be a string\",\n\t\t\t\torganization.id,\n\t\t\t),\n\t\t);\n\t}\n\n\t// Validate organization name\n\tif (organization.name && typeof organization.name !== \"string\") {\n\t\terrors.push(\n\t\t\tcreateError(\n\t\t\t\t\"organization.name\",\n\t\t\t\t\"Organization name must be a string\",\n\t\t\t\torganization.name,\n\t\t\t),\n\t\t);\n\t}\n\n\t// Validate settings\n\tif (organization.settings) {\n\t\tconst { settings } = organization;\n\n\t\t// Validate password policy\n\t\tif (settings.passwordPolicy) {\n\t\t\tif (\n\t\t\t\tsettings.passwordPolicy.minLength &&\n\t\t\t\ttypeof settings.passwordPolicy.minLength !== \"number\"\n\t\t\t) {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateError(\n\t\t\t\t\t\t\"organization.settings.passwordPolicy.minLength\",\n\t\t\t\t\t\t\"Min length must be a number\",\n\t\t\t\t\t\tsettings.passwordPolicy.minLength,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t\tif (\n\t\t\t\tsettings.passwordPolicy.minLength &&\n\t\t\t\tsettings.passwordPolicy.minLength < 4\n\t\t\t) {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateWarning(\n\t\t\t\t\t\t\"organization.settings.passwordPolicy.minLength\",\n\t\t\t\t\t\t\"Minimum password length should be at least 4 characters\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Validate session settings\n\t\tif (settings.sessionSettings) {\n\t\t\tif (\n\t\t\t\tsettings.sessionSettings.maxDuration &&\n\t\t\t\ttypeof settings.sessionSettings.maxDuration !== \"number\"\n\t\t\t) {\n\t\t\t\terrors.push(\n\t\t\t\t\tcreateError(\n\t\t\t\t\t\t\"organization.settings.sessionSettings.maxDuration\",\n\t\t\t\t\t\t\"Max duration must be a number\",\n\t\t\t\t\t\tsettings.sessionSettings.maxDuration,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Validate branding\n\t\tif (settings.branding) {\n\t\t\terrors.push(\n\t\t\t\t...validateBrandingConfig(\n\t\t\t\t\tsettings.branding,\n\t\t\t\t\t\"organization.settings.branding\",\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t}\n\n\treturn errors;\n}\n\n// ============================================================================\n// Component Override Validation\n// ============================================================================\n\n/**\n * Validates component overrides\n */\nexport function validateComponentOverrides(\n\tcomponents: ComponentOverrides,\n): ConfigValidationError[] {\n\tconst errors: ConfigValidationError[] = [];\n\n\tif (!components || typeof components !== \"object\") {\n\t\terrors.push(\n\t\t\tcreateError(\"components\", \"Components must be an object\", components),\n\t\t);\n\t\treturn errors;\n\t}\n\n\t// Validate that each override is a valid React component\n\tObject.entries(components).forEach(([componentName, Component]) => {\n\t\tif (Component && typeof Component !== \"function\") {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\n\t\t\t\t\t`components.${componentName}`,\n\t\t\t\t\t\"Component override must be a React component (function)\",\n\t\t\t\t\tComponent,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t});\n\n\treturn errors;\n}\n\n// ============================================================================\n// Main Configuration Validation\n// ============================================================================\n\n/**\n * Validates the complete Frank Auth UI configuration\n */\nexport function validateFrankAuthConfig(\n\tconfig: Partial<FrankAuthUIConfig>,\n): ConfigValidationResult {\n\tconst errors: ConfigValidationError[] = [];\n\tconst warnings: ConfigValidationError[] = [];\n\n\tif (!config || typeof config !== \"object\") {\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\terrors: [\n\t\t\t\tcreateError(\"config\", \"Configuration must be an object\", config),\n\t\t\t],\n\t\t\twarnings: [],\n\t\t};\n\t}\n\n\t// Validate required fields\n\tif (!config.publishableKey) {\n\t\terrors.push(createError(\"publishableKey\", \"Publishable key is required\"));\n\t} else {\n\t\terrors.push(...validatePublishableKey(config.publishableKey));\n\t}\n\n\tif (!config.userType) {\n\t\terrors.push(createError(\"userType\", \"User type is required\"));\n\t} else {\n\t\terrors.push(...validateUserType(config.userType));\n\t}\n\n\t// Validate optional fields\n\tif (config.apiUrl) {\n\t\tconst apiUrlErrors = validateApiUrl(config.apiUrl);\n\t\terrors.push(...apiUrlErrors.filter((e) => e.path.includes(\"error\")));\n\t\twarnings.push(...apiUrlErrors.filter((e) => e.path.includes(\"warning\")));\n\t}\n\n\tif (config.theme) {\n\t\terrors.push(...validateThemeConfig(config.theme));\n\t}\n\n\tif (config.appearance) {\n\t\terrors.push(...validateAppearanceConfig(config.appearance));\n\t}\n\n\tif (config.localization) {\n\t\terrors.push(...validateLocalizationConfig(config.localization));\n\t}\n\n\tif (config.organization) {\n\t\terrors.push(...validateOrganizationConfig(config.organization));\n\t}\n\n\tif (config.components) {\n\t\terrors.push(...validateComponentOverrides(config.components));\n\t}\n\n\t// Validate features\n\tif (config.features) {\n\t\tif (typeof config.features !== \"object\") {\n\t\t\terrors.push(\n\t\t\t\tcreateError(\"features\", \"Features must be an object\", config.features),\n\t\t\t);\n\t\t} else {\n\t\t\t// Check for at least one authentication method enabled\n\t\t\tif (!config.features.signIn && !config.features.sso) {\n\t\t\t\twarnings.push(\n\t\t\t\t\tcreateWarning(\n\t\t\t\t\t\t\"features\",\n\t\t\t\t\t\t\"At least one authentication method (signIn or sso) should be enabled\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tisValid: errors.length === 0,\n\t\terrors,\n\t\twarnings,\n\t};\n}\n\n// ============================================================================\n// Quick Validation Functions\n// ============================================================================\n\n/**\n * Quick validation that throws on errors\n */\nexport function assertValidConfig(config: Partial<FrankAuthUIConfig>): void {\n\tconst result = validateFrankAuthConfig(config);\n\n\tif (!result.isValid) {\n\t\tconst errorMessages = result.errors.map(\n\t\t\t(error) => `${error.path}: ${error.message}`,\n\t\t);\n\t\tthrow new Error(\n\t\t\t`Invalid Frank Auth configuration:\\n${errorMessages.join(\"\\n\")}`,\n\t\t);\n\t}\n}\n\n/**\n * Validates configuration and returns boolean\n */\nexport function isValidConfig(config: Partial<FrankAuthUIConfig>): boolean {\n\treturn validateFrankAuthConfig(config).isValid;\n}\n\n/**\n * Gets validation errors as formatted strings\n */\nexport function getConfigErrors(config: Partial<FrankAuthUIConfig>): string[] {\n\tconst result = validateFrankAuthConfig(config);\n\treturn result.errors.map((error) => `${error.path}: ${error.message}`);\n}\n\n/**\n * Gets validation warnings as formatted strings\n */\nexport function getConfigWarnings(\n\tconfig: Partial<FrankAuthUIConfig>,\n): string[] {\n\tconst result = validateFrankAuthConfig(config);\n\treturn result.warnings.map(\n\t\t(warning) => `${warning.path}: ${warning.message}`,\n\t);\n}\n"],"names":["createError","path","message","value","createWarning","isValidUrl","url","isValidHexColor","color","isValidCSSValue","isValidOption","options","validatePublishableKey","key","errors","validateApiUrl","validateUserType","userType","validUserTypes","validateLocale","locale","validLocales","validateThemeMode","mode","validModes","validateColorPalette","colors","requiredColors","colorKey","colorValue","requiredShades","shade","validateTypography","typography","size","validateThemeConfig","theme","validateAppearanceMode","validateComponentSize","validSizes","validateColorVariant","variant","validVariants","validateBrandingConfig","branding","validateAppearanceConfig","appearance","components","validateLocalizationConfig","localization","error","index","validateOrganizationConfig","organization","settings","validateComponentOverrides","componentName","Component","validateFrankAuthConfig","config","warnings","apiUrlErrors","e","assertValidConfig","result","errorMessages","isValidConfig","getConfigErrors","getConfigWarnings","warning"],"mappings":"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"}