UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

1 lines 34.6 kB
{"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 AppearanceConfig,\n AppearanceMode,\n ColorVariant,\n ComponentOverrides,\n ComponentSize,\n ConfigValidationError,\n ConfigValidationResult,\n FrankAuthUIConfig,\n Locale,\n LocalizationConfig,\n OrganizationConfig,\n Theme,\n ThemeMode,\n UserType,\n} from './types';\n\n// ============================================================================\n// Validation Utilities\n// ============================================================================\n\n/**\n * Creates a validation error\n */\nfunction createError(path: string, message: string, value?: any): ConfigValidationError {\n return {path, message, value};\n}\n\n/**\n * Creates a validation warning\n */\nfunction createWarning(path: string, message: string, value?: any): ConfigValidationError {\n return {path, message, value};\n}\n\n/**\n * Validates if a value is a valid URL\n */\nfunction isValidUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Validates if a value is a valid hex color\n */\nfunction isValidHexColor(color: string): boolean {\n return /^#([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 // Basic CSS value validation - can be extended\n return 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>(value: string, options: readonly T[]): value is T {\n return 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 return 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 const errors: ConfigValidationError[] = [];\n\n if (!key) {\n errors.push(createError('publishableKey', 'Publishable key is required'));\n return errors;\n }\n\n if (typeof key !== 'string') {\n errors.push(createError('publishableKey', 'Publishable key must be a string', key));\n return errors;\n }\n\n // Check format: pk_test_... or pk_live_...\n if (!/^pk_(test|live)_[a-zA-Z0-9_]+$/.test(key)) {\n errors.push(createError('publishableKey', 'Invalid publishable key format. Expected: pk_test_... or pk_live_...', key));\n }\n\n if (key.length < 20) {\n errors.push(createError('publishableKey', 'Publishable key appears to be too short', key));\n }\n\n return errors;\n}\n\n/**\n * Validates API URL\n */\nexport function validateApiUrl(url?: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!url) {\n return errors; // API URL is optional\n }\n\n if (typeof url !== 'string') {\n errors.push(createError('apiUrl', 'API URL must be a string', url));\n return errors;\n }\n\n if (!isValidUrl(url)) {\n errors.push(createError('apiUrl', 'Invalid API URL format', url));\n }\n\n // Check for HTTPS in production\n if (url.startsWith('http://') && !url.includes('localhost') && !url.includes('127.0.0.1')) {\n errors.push(createWarning('apiUrl', 'Consider using HTTPS for production API URL', url));\n }\n\n return errors;\n}\n\n/**\n * Validates user type\n */\nexport function validateUserType(userType: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n const validUserTypes: UserType[] = ['internal', 'external', 'end_user'];\n\n if (!isValidOption(userType, validUserTypes)) {\n errors.push(createError('userType', `Invalid user type. Must be one of: ${validUserTypes.join(', ')}`, userType));\n }\n\n return errors;\n}\n\n/**\n * Validates locale\n */\nexport function validateLocale(locale: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n const validLocales: Locale[] = ['en', 'es', 'fr', 'de', 'pt', 'it', 'ja', 'ko', 'zh'];\n\n if (!isValidOption(locale, validLocales)) {\n errors.push(createError('locale', `Invalid locale. Must be one of: ${validLocales.join(', ')}`, locale));\n }\n\n return errors;\n}\n\n// ============================================================================\n// Theme Validation\n// ============================================================================\n\n/**\n * Validates theme mode\n */\nexport function validateThemeMode(mode: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n const validModes: ThemeMode[] = ['light', 'dark', 'system'];\n\n if (!isValidOption(mode, validModes)) {\n errors.push(createError('theme.mode', `Invalid theme mode. Must be one of: ${validModes.join(', ')}`, mode));\n }\n\n return errors;\n}\n\n/**\n * Validates color palette\n */\nexport function validateColorPalette(colors: any, path = 'theme.colors'): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!colors || typeof colors !== 'object') {\n errors.push(createError(path, 'Colors must be an object', colors));\n return errors;\n }\n\n // Validate required color properties\n const requiredColors = ['primary', 'secondary', 'background', 'foreground'];\n for (const colorKey of requiredColors) {\n if (!(colorKey in colors)) {\n errors.push(createError(`${path}.${colorKey}`, `Missing required color: ${colorKey}`));\n continue;\n }\n\n const colorValue = colors[colorKey];\n\n // Primary and secondary should be objects with shades\n if (colorKey === 'primary' || colorKey === 'secondary') {\n if (typeof colorValue !== 'object') {\n errors.push(createError(`${path}.${colorKey}`, `${colorKey} must be an object with color shades`, colorValue));\n continue;\n }\n\n // Check for required shades\n const requiredShades = ['DEFAULT', 'foreground'];\n for (const shade of requiredShades) {\n if (!(shade in colorValue)) {\n errors.push(createError(`${path}.${colorKey}.${shade}`, `Missing required shade: ${shade}`));\n } else if (!isValidHexColor(colorValue[shade])) {\n errors.push(createError(`${path}.${colorKey}.${shade}`, 'Invalid hex color format', colorValue[shade]));\n }\n }\n } else {\n // Background, foreground should be hex colors\n if (!isValidHexColor(colorValue)) {\n errors.push(createError(`${path}.${colorKey}`, 'Invalid hex color format', colorValue));\n }\n }\n }\n\n return errors;\n}\n\n/**\n * Validates typography configuration\n */\nexport function validateTypography(typography: any, path = 'theme.typography'): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!typography || typeof typography !== 'object') {\n errors.push(createError(path, 'Typography must be an object', typography));\n return errors;\n }\n\n // Validate font families\n if (typography.fontFamily) {\n if (typeof typography.fontFamily !== 'object') {\n errors.push(createError(`${path}.fontFamily`, 'Font family must be an object', typography.fontFamily));\n } else {\n if (typography.fontFamily.sans && !Array.isArray(typography.fontFamily.sans)) {\n errors.push(createError(`${path}.fontFamily.sans`, 'Sans font family must be an array', typography.fontFamily.sans));\n }\n if (typography.fontFamily.mono && !Array.isArray(typography.fontFamily.mono)) {\n errors.push(createError(`${path}.fontFamily.mono`, 'Mono font family must be an array', typography.fontFamily.mono));\n }\n }\n }\n\n // Validate font sizes\n if (typography.fontSize) {\n if (typeof typography.fontSize !== 'object') {\n errors.push(createError(`${path}.fontSize`, 'Font size must be an object', typography.fontSize));\n } else {\n Object.entries(typography.fontSize).forEach(([size, value]) => {\n if (!Array.isArray(value) || value.length !== 2) {\n errors.push(createError(`${path}.fontSize.${size}`, 'Font size value must be an array with [size, lineHeight]', value));\n }\n });\n }\n }\n\n return errors;\n}\n\n/**\n * Validates complete theme configuration\n */\nexport function validateThemeConfig(theme: Partial<Theme>): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!theme || typeof theme !== 'object') {\n errors.push(createError('theme', 'Theme must be an object', theme));\n return errors;\n }\n\n // Validate theme mode\n if (theme.mode) {\n errors.push(...validateThemeMode(theme.mode));\n }\n\n // Validate colors\n if (theme.colors) {\n errors.push(...validateColorPalette(theme.colors));\n }\n\n // Validate typography\n if (theme.typography) {\n errors.push(...validateTypography(theme.typography));\n }\n\n // Validate spacing\n if (theme.spacing) {\n if (typeof theme.spacing !== 'object') {\n errors.push(createError('theme.spacing', 'Spacing must be an object', theme.spacing));\n } else {\n Object.entries(theme.spacing).forEach(([key, value]) => {\n if (!isValidCSSValue(value as string)) {\n errors.push(createError(`theme.spacing.${key}`, 'Invalid CSS value for spacing', value));\n }\n });\n }\n }\n\n return errors;\n}\n\n// ============================================================================\n// Appearance Validation\n// ============================================================================\n\n/**\n * Validates appearance mode\n */\nexport function validateAppearanceMode(mode: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n const validModes: AppearanceMode[] = ['system', 'light', 'dark'];\n\n if (!isValidOption(mode, validModes)) {\n errors.push(createError('appearance.mode', `Invalid appearance mode. Must be one of: ${validModes.join(', ')}`, mode));\n }\n\n return errors;\n}\n\n/**\n * Validates component size\n */\nexport function validateComponentSize(size: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n const validSizes: ComponentSize[] = ['sm', 'md', 'lg'];\n\n if (!isValidOption(size, validSizes)) {\n errors.push(createError('size', `Invalid component size. Must be one of: ${validSizes.join(', ')}`, size));\n }\n\n return errors;\n}\n\n/**\n * Validates color variant\n */\nexport function validateColorVariant(variant: string): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n const validVariants: ColorVariant[] = ['default', 'primary', 'secondary', 'success', 'warning', 'danger'];\n\n if (!isValidOption(variant, validVariants)) {\n errors.push(createError('color', `Invalid color variant. Must be one of: ${validVariants.join(', ')}`, variant));\n }\n\n return errors;\n}\n\n/**\n * Validates branding configuration\n */\nexport function validateBrandingConfig(branding: any, path = 'appearance.branding'): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!branding || typeof branding !== 'object') {\n errors.push(createError(path, 'Branding must be an object', branding));\n return errors;\n }\n\n // Validate logo\n if (branding.logo) {\n if (branding.logo.url && !isValidUrl(branding.logo.url)) {\n errors.push(createError(`${path}.logo.url`, 'Invalid logo URL', branding.logo.url));\n }\n if (!branding.logo.alt) {\n errors.push(createError(`${path}.logo.alt`, 'Logo alt text is required for accessibility'));\n }\n }\n\n // Validate colors\n if (branding.colors) {\n if (branding.colors.primary && !isValidHexColor(branding.colors.primary)) {\n errors.push(createError(`${path}.colors.primary`, 'Invalid hex color format', branding.colors.primary));\n }\n if (branding.colors.secondary && !isValidHexColor(branding.colors.secondary)) {\n errors.push(createError(`${path}.colors.secondary`, 'Invalid hex color format', branding.colors.secondary));\n }\n }\n\n return errors;\n}\n\n/**\n * Validates appearance configuration\n */\nexport function validateAppearanceConfig(appearance: Partial<AppearanceConfig>): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!appearance || typeof appearance !== 'object') {\n errors.push(createError('appearance', 'Appearance must be an object', appearance));\n return errors;\n }\n\n // Validate appearance mode\n if (appearance.mode) {\n errors.push(...validateAppearanceMode(appearance.mode));\n }\n\n // Validate branding\n if (appearance.branding) {\n errors.push(...validateBrandingConfig(appearance.branding));\n }\n\n // Validate component appearance\n if (appearance.components) {\n const {components} = appearance;\n\n if (components.input?.size) {\n errors.push(...validateComponentSize(components.input.size));\n }\n if (components.input?.color) {\n errors.push(...validateColorVariant(components.input.color));\n }\n if (components.button?.size) {\n errors.push(...validateComponentSize(components.button.size));\n }\n if (components.button?.color) {\n errors.push(...validateColorVariant(components.button.color));\n }\n }\n\n return errors;\n}\n\n// ============================================================================\n// Localization Validation\n// ============================================================================\n\n/**\n * Validates localization configuration\n */\nexport function validateLocalizationConfig(localization: Partial<LocalizationConfig>): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!localization || typeof localization !== 'object') {\n errors.push(createError('localization', 'Localization must be an object', localization));\n return errors;\n }\n\n // Validate default locale\n if (localization.defaultLocale) {\n errors.push(...validateLocale(localization.defaultLocale).map(error => ({\n ...error,\n path: `localization.${error.path}`,\n })));\n }\n\n // Validate fallback locale\n if (localization.fallbackLocale) {\n errors.push(...validateLocale(localization.fallbackLocale).map(error => ({\n ...error,\n path: `localization.${error.path}`,\n })));\n }\n\n // Validate supported locales\n if (localization.supportedLocales) {\n if (!Array.isArray(localization.supportedLocales)) {\n errors.push(createError('localization.supportedLocales', 'Supported locales must be an array', localization.supportedLocales));\n } else {\n localization.supportedLocales.forEach((locale, index) => {\n errors.push(...validateLocale(locale).map(error => ({\n ...error,\n path: `localization.supportedLocales[${index}]`,\n })));\n });\n }\n }\n\n // Validate date/time formats\n if (localization.dateFormat && typeof localization.dateFormat !== 'string') {\n errors.push(createError('localization.dateFormat', 'Date format must be a string', localization.dateFormat));\n }\n\n if (localization.timeFormat && typeof localization.timeFormat !== 'string') {\n errors.push(createError('localization.timeFormat', 'Time format must be a string', localization.timeFormat));\n }\n\n return errors;\n}\n\n// ============================================================================\n// Organization Validation\n// ============================================================================\n\n/**\n * Validates organization configuration\n */\nexport function validateOrganizationConfig(organization: Partial<OrganizationConfig>): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!organization || typeof organization !== 'object') {\n errors.push(createError('organization', 'Organization must be an object', organization));\n return errors;\n }\n\n // Validate organization ID\n if (organization.id && typeof organization.id !== 'string') {\n errors.push(createError('organization.id', 'Organization ID must be a string', organization.id));\n }\n\n // Validate organization name\n if (organization.name && typeof organization.name !== 'string') {\n errors.push(createError('organization.name', 'Organization name must be a string', organization.name));\n }\n\n // Validate settings\n if (organization.settings) {\n const {settings} = organization;\n\n // Validate password policy\n if (settings.passwordPolicy) {\n if (settings.passwordPolicy.minLength && typeof settings.passwordPolicy.minLength !== 'number') {\n errors.push(createError('organization.settings.passwordPolicy.minLength', 'Min length must be a number', settings.passwordPolicy.minLength));\n }\n if (settings.passwordPolicy.minLength && settings.passwordPolicy.minLength < 4) {\n errors.push(createWarning('organization.settings.passwordPolicy.minLength', 'Minimum password length should be at least 4 characters'));\n }\n }\n\n // Validate session settings\n if (settings.sessionSettings) {\n if (settings.sessionSettings.maxDuration && typeof settings.sessionSettings.maxDuration !== 'number') {\n errors.push(createError('organization.settings.sessionSettings.maxDuration', 'Max duration must be a number', settings.sessionSettings.maxDuration));\n }\n }\n\n // Validate branding\n if (settings.branding) {\n errors.push(...validateBrandingConfig(settings.branding, 'organization.settings.branding'));\n }\n }\n\n return errors;\n}\n\n// ============================================================================\n// Component Override Validation\n// ============================================================================\n\n/**\n * Validates component overrides\n */\nexport function validateComponentOverrides(components: ComponentOverrides): ConfigValidationError[] {\n const errors: ConfigValidationError[] = [];\n\n if (!components || typeof components !== 'object') {\n errors.push(createError('components', 'Components must be an object', components));\n return errors;\n }\n\n // Validate that each override is a valid React component\n Object.entries(components).forEach(([componentName, Component]) => {\n if (Component && typeof Component !== 'function') {\n errors.push(createError(`components.${componentName}`, 'Component override must be a React component (function)', Component));\n }\n });\n\n return errors;\n}\n\n// ============================================================================\n// Main Configuration Validation\n// ============================================================================\n\n/**\n * Validates the complete Frank Auth UI configuration\n */\nexport function validateFrankAuthConfig(config: Partial<FrankAuthUIConfig>): ConfigValidationResult {\n const errors: ConfigValidationError[] = [];\n const warnings: ConfigValidationError[] = [];\n\n if (!config || typeof config !== 'object') {\n return {\n isValid: false,\n errors: [createError('config', 'Configuration must be an object', config)],\n warnings: [],\n };\n }\n\n // Validate required fields\n if (!config.publishableKey) {\n errors.push(createError('publishableKey', 'Publishable key is required'));\n } else {\n errors.push(...validatePublishableKey(config.publishableKey));\n }\n\n if (!config.userType) {\n errors.push(createError('userType', 'User type is required'));\n } else {\n errors.push(...validateUserType(config.userType));\n }\n\n // Validate optional fields\n if (config.apiUrl) {\n const apiUrlErrors = validateApiUrl(config.apiUrl);\n errors.push(...apiUrlErrors.filter(e => e.path.includes('error')));\n warnings.push(...apiUrlErrors.filter(e => e.path.includes('warning')));\n }\n\n if (config.theme) {\n errors.push(...validateThemeConfig(config.theme));\n }\n\n if (config.appearance) {\n errors.push(...validateAppearanceConfig(config.appearance));\n }\n\n if (config.localization) {\n errors.push(...validateLocalizationConfig(config.localization));\n }\n\n if (config.organization) {\n errors.push(...validateOrganizationConfig(config.organization));\n }\n\n if (config.components) {\n errors.push(...validateComponentOverrides(config.components));\n }\n\n // Validate features\n if (config.features) {\n if (typeof config.features !== 'object') {\n errors.push(createError('features', 'Features must be an object', config.features));\n } else {\n // Check for at least one authentication method enabled\n if (!config.features.signIn && !config.features.sso) {\n warnings.push(createWarning('features', 'At least one authentication method (signIn or sso) should be enabled'));\n }\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\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 const result = validateFrankAuthConfig(config);\n\n if (!result.isValid) {\n const errorMessages = result.errors.map(error => `${error.path}: ${error.message}`);\n throw new Error(`Invalid Frank Auth configuration:\\n${errorMessages.join('\\n')}`);\n }\n}\n\n/**\n * Validates configuration and returns boolean\n */\nexport function isValidConfig(config: Partial<FrankAuthUIConfig>): boolean {\n return validateFrankAuthConfig(config).isValid;\n}\n\n/**\n * Gets validation errors as formatted strings\n */\nexport function getConfigErrors(config: Partial<FrankAuthUIConfig>): string[] {\n const result = validateFrankAuthConfig(config);\n return result.errors.map(error => `${error.path}: ${error.message}`);\n}\n\n/**\n * Gets validation warnings as formatted strings\n */\nexport function getConfigWarnings(config: Partial<FrankAuthUIConfig>): string[] {\n const result = validateFrankAuthConfig(config);\n return result.warnings.map(warning => `${warning.path}: ${warning.message}`);\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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"}