UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

196 lines (195 loc) 10.3 kB
function o(e, s, t) { return { path: e, message: s, value: t }; } function p(e, s, t) { return { path: e, message: s, value: t }; } function h(e) { try { return new URL(e), !0; } catch { return !1; } } function l(e) { return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(e); } function g(e) { return typeof e == "string" && e.length > 0; } function u(e, s) { return s.includes(e); } function $(e) { const s = []; return e ? typeof e != "string" ? (s.push(o("publishableKey", "Publishable key must be a string", e)), s) : (/^pk_(test|live)_[a-zA-Z0-9_]+$/.test(e) || s.push(o("publishableKey", "Invalid publishable key format. Expected: pk_test_... or pk_live_...", e)), e.length < 20 && s.push(o("publishableKey", "Publishable key appears to be too short", e)), s) : (s.push(o("publishableKey", "Publishable key is required")), s); } function v(e) { const s = []; return e ? typeof e != "string" ? (s.push(o("apiUrl", "API URL must be a string", e)), s) : (h(e) || s.push(o("apiUrl", "Invalid API URL format", e)), e.startsWith("http://") && !e.includes("localhost") && !e.includes("127.0.0.1") && s.push(p("apiUrl", "Consider using HTTPS for production API URL", e)), s) : s; } function j(e) { const s = [], t = ["internal", "external", "end_user"]; return u(e, t) || s.push(o("userType", `Invalid user type. Must be one of: ${t.join(", ")}`, e)), s; } function c(e) { const s = [], t = ["en", "es", "fr", "de", "pt", "it", "ja", "ko", "zh"]; return u(e, t) || s.push(o("locale", `Invalid locale. Must be one of: ${t.join(", ")}`, e)), s; } function F(e) { const s = [], t = ["light", "dark", "system"]; return u(e, t) || s.push(o("theme.mode", `Invalid theme mode. Must be one of: ${t.join(", ")}`, e)), s; } function L(e, s = "theme.colors") { const t = []; if (!e || typeof e != "object") return t.push(o(s, "Colors must be an object", e)), t; const i = ["primary", "secondary", "background", "foreground"]; for (const r of i) { if (!(r in e)) { t.push(o(`${s}.${r}`, `Missing required color: ${r}`)); continue; } const n = e[r]; if (r === "primary" || r === "secondary") { if (typeof n != "object") { t.push(o(`${s}.${r}`, `${r} must be an object with color shades`, n)); continue; } const y = ["DEFAULT", "foreground"]; for (const a of y) a in n ? l(n[a]) || t.push(o(`${s}.${r}.${a}`, "Invalid hex color format", n[a])) : t.push(o(`${s}.${r}.${a}`, `Missing required shade: ${a}`)); } else l(n) || t.push(o(`${s}.${r}`, "Invalid hex color format", n)); } return t; } function A(e, s = "theme.typography") { const t = []; return !e || typeof e != "object" ? (t.push(o(s, "Typography must be an object", e)), t) : (e.fontFamily && (typeof e.fontFamily != "object" ? t.push(o(`${s}.fontFamily`, "Font family must be an object", e.fontFamily)) : (e.fontFamily.sans && !Array.isArray(e.fontFamily.sans) && t.push(o(`${s}.fontFamily.sans`, "Sans font family must be an array", e.fontFamily.sans)), e.fontFamily.mono && !Array.isArray(e.fontFamily.mono) && t.push(o(`${s}.fontFamily.mono`, "Mono font family must be an array", e.fontFamily.mono)))), e.fontSize && (typeof e.fontSize != "object" ? t.push(o(`${s}.fontSize`, "Font size must be an object", e.fontSize)) : Object.entries(e.fontSize).forEach(([i, r]) => { (!Array.isArray(r) || r.length !== 2) && t.push(o(`${s}.fontSize.${i}`, "Font size value must be an array with [size, lineHeight]", r)); })), t); } function S(e) { const s = []; return !e || typeof e != "object" ? (s.push(o("theme", "Theme must be an object", e)), s) : (e.mode && s.push(...F(e.mode)), e.colors && s.push(...L(e.colors)), e.typography && s.push(...A(e.typography)), e.spacing && (typeof e.spacing != "object" ? s.push(o("theme.spacing", "Spacing must be an object", e.spacing)) : Object.entries(e.spacing).forEach(([t, i]) => { g(i) || s.push(o(`theme.spacing.${t}`, "Invalid CSS value for spacing", i)); })), s); } function C(e) { const s = [], t = ["system", "light", "dark"]; return u(e, t) || s.push(o("appearance.mode", `Invalid appearance mode. Must be one of: ${t.join(", ")}`, e)), s; } function m(e) { const s = [], t = ["sm", "md", "lg"]; return u(e, t) || s.push(o("size", `Invalid component size. Must be one of: ${t.join(", ")}`, e)), s; } function d(e) { const s = [], t = ["default", "primary", "secondary", "success", "warning", "danger"]; return u(e, t) || s.push(o("color", `Invalid color variant. Must be one of: ${t.join(", ")}`, e)), s; } function b(e, s = "appearance.branding") { const t = []; return !e || typeof e != "object" ? (t.push(o(s, "Branding must be an object", e)), t) : (e.logo && (e.logo.url && !h(e.logo.url) && t.push(o(`${s}.logo.url`, "Invalid logo URL", e.logo.url)), e.logo.alt || t.push(o(`${s}.logo.alt`, "Logo alt text is required for accessibility"))), e.colors && (e.colors.primary && !l(e.colors.primary) && t.push(o(`${s}.colors.primary`, "Invalid hex color format", e.colors.primary)), e.colors.secondary && !l(e.colors.secondary) && t.push(o(`${s}.colors.secondary`, "Invalid hex color format", e.colors.secondary))), t); } function I(e) { const s = []; if (!e || typeof e != "object") return s.push(o("appearance", "Appearance must be an object", e)), s; if (e.mode && s.push(...C(e.mode)), e.branding && s.push(...b(e.branding)), e.components) { const { components: t } = e; t.input?.size && s.push(...m(t.input.size)), t.input?.color && s.push(...d(t.input.color)), t.button?.size && s.push(...m(t.button.size)), t.button?.color && s.push(...d(t.button.color)); } return s; } function w(e) { const s = []; return !e || typeof e != "object" ? (s.push(o("localization", "Localization must be an object", e)), s) : (e.defaultLocale && s.push(...c(e.defaultLocale).map((t) => ({ ...t, path: `localization.${t.path}` }))), e.fallbackLocale && s.push(...c(e.fallbackLocale).map((t) => ({ ...t, path: `localization.${t.path}` }))), e.supportedLocales && (Array.isArray(e.supportedLocales) ? e.supportedLocales.forEach((t, i) => { s.push(...c(t).map((r) => ({ ...r, path: `localization.supportedLocales[${i}]` }))); }) : s.push(o("localization.supportedLocales", "Supported locales must be an array", e.supportedLocales))), e.dateFormat && typeof e.dateFormat != "string" && s.push(o("localization.dateFormat", "Date format must be a string", e.dateFormat)), e.timeFormat && typeof e.timeFormat != "string" && s.push(o("localization.timeFormat", "Time format must be a string", e.timeFormat)), s); } function P(e) { const s = []; if (!e || typeof e != "object") return s.push(o("organization", "Organization must be an object", e)), s; if (e.id && typeof e.id != "string" && s.push(o("organization.id", "Organization ID must be a string", e.id)), e.name && typeof e.name != "string" && s.push(o("organization.name", "Organization name must be a string", e.name)), e.settings) { const { settings: t } = e; t.passwordPolicy && (t.passwordPolicy.minLength && typeof t.passwordPolicy.minLength != "number" && s.push(o("organization.settings.passwordPolicy.minLength", "Min length must be a number", t.passwordPolicy.minLength)), t.passwordPolicy.minLength && t.passwordPolicy.minLength < 4 && s.push(p("organization.settings.passwordPolicy.minLength", "Minimum password length should be at least 4 characters"))), t.sessionSettings && t.sessionSettings.maxDuration && typeof t.sessionSettings.maxDuration != "number" && s.push(o("organization.settings.sessionSettings.maxDuration", "Max duration must be a number", t.sessionSettings.maxDuration)), t.branding && s.push(...b(t.branding, "organization.settings.branding")); } return s; } function M(e) { const s = []; return !e || typeof e != "object" ? (s.push(o("components", "Components must be an object", e)), s) : (Object.entries(e).forEach(([t, i]) => { i && typeof i != "function" && s.push(o(`components.${t}`, "Component override must be a React component (function)", i)); }), s); } function f(e) { const s = [], t = []; if (!e || typeof e != "object") return { isValid: !1, errors: [o("config", "Configuration must be an object", e)], warnings: [] }; if (e.publishableKey ? s.push(...$(e.publishableKey)) : s.push(o("publishableKey", "Publishable key is required")), e.userType ? s.push(...j(e.userType)) : s.push(o("userType", "User type is required")), e.apiUrl) { const i = v(e.apiUrl); s.push(...i.filter((r) => r.path.includes("error"))), t.push(...i.filter((r) => r.path.includes("warning"))); } return e.theme && s.push(...S(e.theme)), e.appearance && s.push(...I(e.appearance)), e.localization && s.push(...w(e.localization)), e.organization && s.push(...P(e.organization)), e.components && s.push(...M(e.components)), e.features && (typeof e.features != "object" ? s.push(o("features", "Features must be an object", e.features)) : !e.features.signIn && !e.features.sso && t.push(p("features", "At least one authentication method (signIn or sso) should be enabled"))), { isValid: s.length === 0, errors: s, warnings: t }; } function U(e) { const s = f(e); if (!s.isValid) { const t = s.errors.map((i) => `${i.path}: ${i.message}`); throw new Error(`Invalid Frank Auth configuration: ${t.join(` `)}`); } } function z(e) { return f(e).isValid; } function x(e) { return f(e).errors.map((t) => `${t.path}: ${t.message}`); } function T(e) { return f(e).warnings.map((t) => `${t.path}: ${t.message}`); } export { U as assertValidConfig, x as getConfigErrors, T as getConfigWarnings, z as isValidConfig, v as validateApiUrl, I as validateAppearanceConfig, C as validateAppearanceMode, b as validateBrandingConfig, L as validateColorPalette, d as validateColorVariant, M as validateComponentOverrides, m as validateComponentSize, f as validateFrankAuthConfig, c as validateLocale, w as validateLocalizationConfig, P as validateOrganizationConfig, $ as validatePublishableKey, S as validateThemeConfig, F as validateThemeMode, A as validateTypography, j as validateUserType }; //# sourceMappingURL=validators.js.map