UNPKG

@gsb-core/core

Version:

GSB core services and classes for platform-independent web applications

461 lines 15.6 kB
"use strict"; /** * GSB Configuration - Core settings and tenant management * Consolidated version with improved tenant handling */ Object.defineProperty(exports, "__esModule", { value: true }); exports.GSB_CONFIG = void 0; exports.setLocalStorage = setLocalStorage; exports.getLocalStorage = getLocalStorage; exports.removeLocalStorage = removeLocalStorage; exports.getEnvVar = getEnvVar; exports.checkAllEnvVars = checkAllEnvVars; exports.getGsbBaseDomain = getGsbBaseDomain; exports.getGsbApiUrl = getGsbApiUrl; exports.getGsbLangCode = getGsbLangCode; exports.getGsbLangStorageKey = getGsbLangStorageKey; exports.getDefaultTenant = getDefaultTenant; exports.getGsbTenantCode = getGsbTenantCode; exports.setGsbTenantCode = setGsbTenantCode; exports.setGsbApiUrl = setGsbApiUrl; exports.setGsbLangCode = setGsbLangCode; exports.setGsbLangStorageKey = setGsbLangStorageKey; exports.setGsbToken = setGsbToken; exports.getGsbToken = getGsbToken; exports.isMultiTenantEnabled = isMultiTenantEnabled; exports.getTenantFromHostname = getTenantFromHostname; exports.extractTenantCodeFromToken = extractTenantCodeFromToken; exports.getEnvToken = getEnvToken; exports.getTokenStorageKey = getTokenStorageKey; exports.getUserDataStorageKey = getUserDataStorageKey; exports.getAvailableTenants = getAvailableTenants; exports.clearGsbAuth = clearGsbAuth; // Environment detection const isBrowser = typeof window !== 'undefined'; const isCloudflareWorker = typeof process === 'undefined' && typeof globalThis !== 'undefined' && 'caches' in globalThis; // Storage keys const STORAGE = { ACTIVE_TENANT: 'gsb_active_tenant', TOKEN_PREFIX: 'gsb_auth_', USER_PREFIX: 'gsb_user_' }; // GSB_SETTINGS is now a cache. Values will be populated by getters. const GSB_SETTINGS = { TENANT_CODE: undefined, TOKEN: undefined, BASE_DOMAIN: undefined, API_URL: undefined, LANG_STORAGE_KEY: undefined, LANG_CODE: undefined }; // Default cache duration (infinite) const DEFAULT_CACHE_DURATION = Number.MAX_SAFE_INTEGER; // Infinite duration function setLocalStorage(key, value, duration = DEFAULT_CACHE_DURATION) { if (typeof localStorage !== 'undefined') { try { const storageData = { data: value, timestamp: Date.now(), expiry: Date.now() + duration, isPrimitive: true // strings are primitives }; localStorage.setItem(key, JSON.stringify(storageData)); } catch (error) { console.error(`Error storing data in localStorage with key ${key}:`, error); } } } function getLocalStorage(key) { if (typeof localStorage !== 'undefined') { try { const storedData = localStorage.getItem(key); if (storedData) { try { const parsedData = JSON.parse(storedData); // Check if it's in the new format (has expiry) if (parsedData.expiry) { // Check if data is still valid if (Date.now() < parsedData.expiry) { return parsedData.data; } else { // Data expired, remove from localStorage localStorage.removeItem(key); return null; } } else { // It's in the old format (direct string) or custom format // Just return it as-is for backward compatibility return storedData; } } catch (e) { // If we can't parse as JSON, it's likely a direct string from old version return storedData; } } } catch (error) { console.error(`Error retrieving data from localStorage with key ${key}:`, error); } return null; } return null; } function removeLocalStorage(key) { if (typeof localStorage !== 'undefined') { localStorage.removeItem(key); } } // Environment variable access helper function getEnvVar(key, defaultValue) { var _a, _b, _c, _d, _e; if (isBrowser) { return (_b = (_a = window.ENV) === null || _a === void 0 ? void 0 : _a[key]) !== null && _b !== void 0 ? _b : defaultValue; } if (isCloudflareWorker) { return (_d = (_c = globalThis.ENV) === null || _c === void 0 ? void 0 : _c[key]) !== null && _d !== void 0 ? _d : defaultValue; } if (typeof process !== "undefined" && process.env) { return (_e = process.env[key]) !== null && _e !== void 0 ? _e : defaultValue; } return defaultValue; } function checkAllEnvVars(varName) { const nextVarName = `NEXT_PUBLIC_${varName}`; const viteVarName = `VITE_${varName}`; const envVarName = `GSB_${varName}`; return getEnvVar(varName, '') || getEnvVar(nextVarName, '') || getEnvVar(viteVarName, '') || getEnvVar(envVarName, ''); } /** * Get the base domain for GSB services * @returns The base domain */ function getGsbBaseDomain() { if (GSB_SETTINGS.BASE_DOMAIN) { return GSB_SETTINGS.BASE_DOMAIN; } const domainFromEnv = checkAllEnvVars('GSB_BASE_DOMAIN'); if (domainFromEnv) { GSB_SETTINGS.BASE_DOMAIN = domainFromEnv; return domainFromEnv; } // Fallback to a default domain if not set const defaultDomain = 'gsbapps.net'; // Or any other appropriate default GSB_SETTINGS.BASE_DOMAIN = defaultDomain; return defaultDomain; } /** * Get the API URL for GSB services * @returns The API URL */ function getGsbApiUrl() { if (GSB_SETTINGS.API_URL) { return GSB_SETTINGS.API_URL; } const apiUrlFromEnv = checkAllEnvVars('GSB_API_URL'); if (apiUrlFromEnv) { GSB_SETTINGS.API_URL = apiUrlFromEnv; return apiUrlFromEnv; } return undefined; } function getGsbLangCode() { if (GSB_SETTINGS.LANG_CODE) { return GSB_SETTINGS.LANG_CODE; } const storedLangCode = getLocalStorage(getGsbLangStorageKey()); if (storedLangCode) { return storedLangCode; } return undefined; } function getGsbLangStorageKey() { if (GSB_SETTINGS.LANG_STORAGE_KEY) { return GSB_SETTINGS.LANG_STORAGE_KEY; } const langStorageKeyFromEnv = checkAllEnvVars('GSB_LANG_STORAGE_KEY'); if (langStorageKeyFromEnv) { GSB_SETTINGS.LANG_STORAGE_KEY = langStorageKeyFromEnv; return langStorageKeyFromEnv; } return 'gsb_lang_code'; } /** * Get the default tenant code from environment variables * @returns The default tenant code from environment variables, or an empty string if not found. */ function getDefaultTenant() { return checkAllEnvVars('GSB_TENANT_CODE'); } /** * Get the current GSB tenant code * Prioritizes GSB_SETTINGS, then environment variables, then localStorage. * @returns The current active tenant code */ function getGsbTenantCode() { if (GSB_SETTINGS.TENANT_CODE) { return GSB_SETTINGS.TENANT_CODE; } const envTenant = checkAllEnvVars('GSB_TENANT_CODE'); if (envTenant) { GSB_SETTINGS.TENANT_CODE = envTenant; return envTenant; } const storedTenant = getLocalStorage(STORAGE.ACTIVE_TENANT); if (storedTenant) { GSB_SETTINGS.TENANT_CODE = storedTenant; return storedTenant; } if (GSB_SETTINGS.TOKEN) { const extractedTenant = extractTenantCodeFromToken(GSB_SETTINGS.TOKEN); if (extractedTenant) { GSB_SETTINGS.TENANT_CODE = extractedTenant; setLocalStorage(STORAGE.ACTIVE_TENANT, extractedTenant); return extractedTenant; } } // If no tenant code is found anywhere, it might return an empty string // or you might want to throw an error or return a specific default. // For now, it implicitly returns undefined if nothing is found, which becomes empty string via `?? ''` in some uses. // Let's explicitly set it to empty string if nothing found. GSB_SETTINGS.TENANT_CODE = ''; return ''; } /** * Set the active GSB tenant code * @param tenantCode The tenant code to set as active */ function setGsbTenantCode(tenantCode) { GSB_SETTINGS.TENANT_CODE = tenantCode; setLocalStorage(STORAGE.ACTIVE_TENANT, tenantCode); } /** * Set the GSB API URL. * @param apiUrl The API URL to set. */ function setGsbApiUrl(apiUrl) { GSB_SETTINGS.API_URL = apiUrl; } /** * Set the GSB language code. /** * Set the GSB language code. * @param langCode The language code to set. */ function setGsbLangCode(langCode) { GSB_SETTINGS.LANG_CODE = langCode; if (langCode) { setLocalStorage(getGsbLangStorageKey(), langCode); } } function setGsbLangStorageKey(langStorageKey) { GSB_SETTINGS.LANG_STORAGE_KEY = langStorageKey; } /** * Set the GSB token. * @param token The token to set. */ function setGsbToken(token) { GSB_SETTINGS.TOKEN = token; if (token) { const extractedTenant = extractTenantCodeFromToken(token); if (extractedTenant) { // If GSB_SETTINGS.TENANT_CODE is not already set, or if it's different, update it. // This ensures consistency if a token for a different tenant is set. if (!GSB_SETTINGS.TENANT_CODE || GSB_SETTINGS.TENANT_CODE !== extractedTenant) { setGsbTenantCode(extractedTenant); // This will also update localStorage } } const tenantCode = getGsbTenantCode(); if (tenantCode) { setLocalStorage(getTokenStorageKey(tenantCode), token); } } else { const tenantCode = getGsbTenantCode(); if (tenantCode) { removeLocalStorage(getTokenStorageKey(tenantCode)); } } } /** * Get the GSB token. * Prioritizes GSB_SETTINGS, then environment variables, then localStorage for the current tenant. */ function getGsbToken() { if (GSB_SETTINGS.TOKEN) { return GSB_SETTINGS.TOKEN; } const envToken = checkAllEnvVars('GSB_TOKEN'); if (envToken) { GSB_SETTINGS.TOKEN = envToken; return envToken; } const currentTenant = getGsbTenantCode(); // Ensures tenant context is resolved if (currentTenant) { const storedToken = getLocalStorage(getTokenStorageKey(currentTenant)); if (storedToken) { GSB_SETTINGS.TOKEN = storedToken; return storedToken; } } GSB_SETTINGS.TOKEN = ''; // Default to empty string if no token found return ''; } /** * Check if multi-tenant mode is enabled */ function isMultiTenantEnabled() { return checkAllEnvVars('ENABLE_MULTI_TENANT') === 'true'; } /** * Parse tenant code from hostname * @param hostname The hostname to extract tenant from * @returns Tenant code or null if using main domain */ function getTenantFromHostname(hostname) { // In production, check for subdomain const parts = hostname.split('.'); if (parts.length > 2 && parts[0] !== 'www' && parts[0] !== 'app') { return parts[0]; } // Otherwise it's the main domain (default tenant) return null; } /** * Extract tenant code from a JWT token * @param token The JWT token * @returns The tenant code or undefined */ function extractTenantCodeFromToken(token) { try { const base64Url = token.split('.')[1]; const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); const payload = JSON.parse(atob(base64)); return payload.tc || undefined; } catch (_a) { return undefined; } } /** * Get a token from environment variables based on tenant code (for development) * @param tenantCode The tenant code * @returns The token from environment if available, or null */ function getEnvToken() { return getGsbToken(); } /** * Storage key helper for tokens * @param tenantCode The tenant code * @returns Storage key for the tenant's token */ function getTokenStorageKey(tenantCode) { return `${STORAGE.TOKEN_PREFIX}${tenantCode}`; } /** * Storage key helper for user data * @param tenantCode The tenant code * @returns Storage key for the tenant's user data */ function getUserDataStorageKey(tenantCode) { return `${STORAGE.USER_PREFIX}${tenantCode}`; } /** * Get available tenants from storage */ function getAvailableTenants() { if (typeof window === 'undefined') { return [getDefaultTenant()]; } try { const availableTenants = new Set(); // Add current default availableTenants.add(getDefaultTenant()); // Get active tenant if different const activeTenant = localStorage.getItem(STORAGE.ACTIVE_TENANT); if (activeTenant) { availableTenants.add(activeTenant); } // Find all tenants with tokens Object.keys(localStorage).forEach(key => { if (key.startsWith(STORAGE.TOKEN_PREFIX)) { const tenantCode = key.replace(STORAGE.TOKEN_PREFIX, ''); availableTenants.add(tenantCode); } }); return Array.from(availableTenants); } catch (error) { console.error('Error getting available tenants:', error); return [getDefaultTenant()]; } } /** * @deprecated Use setGsbTenantCode and appropriate auth service methods to clear tokens. */ function clearGsbAuth() { GSB_SETTINGS.TOKEN = ''; // GSB_SETTINGS.TENANT_CODE is not cleared here, // as tenant context might still be relevant or derived from other sources (e.g., hostname, default env). // If explicit tenant clearing is needed, use setGsbTenantCode(''). // Also, explicitly remove token from localStorage for current tenant. if (typeof localStorage !== 'undefined') { const currentTenant = getGsbTenantCode(); if (currentTenant) { localStorage.removeItem(getTokenStorageKey(currentTenant)); } // Optionally, clear active tenant if that's desired behavior for clearGsbAuth // localStorage.removeItem(STORAGE.ACTIVE_TENANT); } } /** * GSB Environment Configuration */ exports.GSB_CONFIG = { // Base domain configuration get BASE_DOMAIN() { return getGsbBaseDomain(); }, // Default tenant codes get TENANT_CODE() { return getGsbTenantCode(); }, // API URLs constructed using tenant and base domain API_URL(tenantCode, baseDomain) { const apiUrl = getGsbApiUrl(); if (apiUrl) { return apiUrl; } const tenant = tenantCode || this.TENANT_CODE; const domain = baseDomain || this.BASE_DOMAIN; return `https://${tenant}.${domain}`; }, // Language code get LANG_CODE() { return getGsbLangCode(); }, // Language storage key get LANG_STORAGE_KEY() { return getGsbLangStorageKey(); }, // Multi-tenant support get ENABLE_MULTI_TENANT() { return isMultiTenantEnabled(); }, // Function for extracting tenant code from token extractTenantCode: extractTenantCodeFromToken, // Helper function to build tenant-specific URL getTenantUrl(tenantCode) { if (!tenantCode) { throw new Error('Tenant code is required to construct URL'); } const domain = this.BASE_DOMAIN; return `https://${tenantCode}.${domain}`; } }; //# sourceMappingURL=gsb-config.js.map