UNPKG

@frank-auth/react

Version:

Flexible and customizable React UI components for Frank Authentication

453 lines (452 loc) 11.9 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|standalone)_[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 n = ["primary", "secondary", "background", "foreground"]; for (const r of n) { if (!(r in e)) { t.push( o( `${s}.${r}`, `Missing required color: ${r}` ) ); continue; } const i = e[r]; if (r === "primary" || r === "secondary") { if (typeof i != "object") { t.push( o( `${s}.${r}`, `${r} must be an object with color shades`, i ) ); continue; } const y = ["DEFAULT", "foreground"]; for (const a of y) a in i ? l(i[a]) || t.push( o( `${s}.${r}.${a}`, "Invalid hex color format", i[a] ) ) : t.push( o( `${s}.${r}.${a}`, `Missing required shade: ${a}` ) ); } else l(i) || t.push( o( `${s}.${r}`, "Invalid hex color format", i ) ); } 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(([n, r]) => { (!Array.isArray(r) || r.length !== 2) && t.push( o( `${s}.fontSize.${n}`, "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, n]) => { g(n) || s.push( o( `theme.spacing.${t}`, "Invalid CSS value for spacing", n ) ); })), 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 d(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 m(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(...d(t.input.size)), t.input?.color && s.push(...m(t.input.color)), t.button?.size && s.push(...d(t.button.size)), t.button?.color && s.push(...m(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, n) => { s.push( ...c(t).map((r) => ({ ...r, path: `localization.supportedLocales[${n}]` })) ); }) : 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, n]) => { n && typeof n != "function" && s.push( o( `components.${t}`, "Component override must be a React component (function)", n ) ); }), 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 n = v(e.apiUrl); s.push(...n.filter((r) => r.path.includes("error"))), t.push(...n.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( (n) => `${n.path}: ${n.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, m as validateColorVariant, M as validateComponentOverrides, d 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