UNPKG

@shelchin/svelte-i18n

Version:

The last Svelte i18n library you'll ever need. Type-safe, AI-powered, zero-config.

91 lines (90 loc) 3.55 kB
import { detectBrowserLanguage as detectBrowserLang } from './browser-detection.js'; export function getNestedValue(obj, path) { const result = path .split('.') .reduce((current, key) => current?.[key], obj); return result === undefined ? null : result; } export function interpolate(template, params = {}, config = {}) { const prefix = config?.prefix || '{'; const suffix = config?.suffix || '}'; const regex = new RegExp(`${escapeRegex(prefix)}([^${escapeRegex(suffix)}]+)${escapeRegex(suffix)}`, 'g'); return template.replace(regex, (match, key) => { const value = params[key.trim()]; return value !== undefined ? String(value) : match; }); } export function pluralize(template, count, locale = 'en', rules) { const parts = template.split('|').map((s) => s.trim()); if (parts.length === 1) return parts[0]; const pluralRule = rules?.[locale] || defaultPluralRule; const index = Math.min(pluralRule(count), parts.length - 1); return parts[index] || parts[parts.length - 1]; } function defaultPluralRule(count) { if (count === 0) return 0; if (count === 1) return 0; return 1; } function escapeRegex(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } export function validateSchema(translations, schema, path = '') { const errors = []; for (const key in schema) { const fullPath = path ? `${path}.${key}` : key; const schemaValue = schema[key]; const translationValue = translations?.[key]; if (translationValue === undefined) { errors.push(`Missing translation: ${fullPath}`); } else if (Array.isArray(schemaValue)) { // Handle array validation if (!Array.isArray(translationValue)) { errors.push(`Type mismatch at ${fullPath}: expected array, got ${typeof translationValue}`); } else if (schemaValue.length !== translationValue.length) { errors.push(`Array length mismatch at ${fullPath}: expected ${schemaValue.length} items, got ${translationValue.length}`); } } else if (typeof schemaValue === 'object' && schemaValue !== null) { if (typeof translationValue !== 'object' || translationValue === null) { errors.push(`Type mismatch at ${fullPath}: expected object, got ${typeof translationValue}`); } else { errors.push(...validateSchema(translationValue, schemaValue, fullPath)); } } else if (typeof schemaValue === 'string' && typeof translationValue !== 'string') { errors.push(`Type mismatch at ${fullPath}: expected string, got ${typeof translationValue}`); } } return errors; } export function detectBrowserLanguage() { const browserLang = detectBrowserLang(); if (browserLang) { return browserLang.split('-')[0]; } return null; } export function mergeTranslations(base, override) { const result = { ...base }; for (const key in override) { const overrideValue = override[key]; const baseValue = base[key]; if (typeof overrideValue === 'object' && typeof baseValue === 'object' && !Array.isArray(overrideValue) && !Array.isArray(baseValue)) { result[key] = mergeTranslations(baseValue, overrideValue); } else { result[key] = overrideValue; } } return result; }