{"version":3,"file":"index.mjs","sources":[""],"sourcesContent":["import { unflatten } from \"flat\";\r\nimport { constants } from \"../../../constants\";\r\nimport type { TLocalisationSource } from \"../../../types/localisation\";\r\n\r\ntype TLocaleSource = TLocalisationSource;\r\ntype TLocaleDictionary = TLocaleSource[string];\r\ntype TLocaleValue = TLocaleDictionary[string][number];\r\ntype TFlatLocaleSource = Record<string, unknown>;\r\n\r\n/**\r\n * Тип для одного языка в формате i18next resources.\r\n * Структура: { [ns: string]: { [key: string]: TLocaleValue } }\r\n */\r\ntype TLanguageResources = Record<string, Record<string, TLocaleValue>>;\r\n\r\n/**\r\n * Полный формат resources для i18next.\r\n * Структура: { [lang: string]: { [type: string]: TLanguageResources } }\r\n */\r\ntype TResources = Record<string, Record<string, TLanguageResources>>;\r\n\r\n/**\r\n * Проверяет, является ли значение обычным объектом (не null, не массив)\r\n * @returns {boolean}\r\n */\r\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\r\n  return typeof value === \"object\" && value !== null && !Array.isArray(value);\r\n};\r\n\r\n/**\r\n * Проверяет, является ли значение допустимым значением локали (строка или функция)\r\n * @returns {boolean}\r\n */\r\nconst isLocaleValue = (value: unknown): value is TLocaleValue => {\r\n  return typeof value === \"string\" || typeof value === \"function\";\r\n};\r\n\r\n/**\r\n * Получает плоский объект ресурсов для указанного namespace.\r\n * Преобразует вложенную структуру { name: { key: value } } в плоскую { \"name.key\": value }.\r\n *\r\n * @param values{TLocaleSource} исходные данные локализации\r\n * @param ns{string} пространство имён\r\n * @returns {TFlatLocaleSource} плоский объект с ключами вида \"name.key\"\r\n * @example\r\n * const source = {\r\n *   translation: {\r\n *     forms: { invalidInput: [\"Ошибка\", \"Error\"] },\r\n *     buttons: { submit: [\"Отправить\", \"Submit\"] }\r\n *   }\r\n * };\r\n * getFlatResourceValues(source, \"translation\");\r\n * // { \"forms.invalidInput\": [\"Ошибка\", \"Error\"], \"buttons.submit\": [\"Отправить\", \"Submit\"] }\r\n */\r\nconst getFlatResourceValues = (values: TLocaleSource = {}, ns: string = \"\"): TFlatLocaleSource => {\r\n  const result: Record<string, unknown> = {};\r\n\r\n  if (!ns) {\r\n    return result;\r\n  }\r\n\r\n  const namespacedValues = values[ns];\r\n  if (!isRecord(namespacedValues)) {\r\n    return result;\r\n  }\r\n\r\n  Object.entries(namespacedValues).forEach(([ name, value ]) => {\r\n    if (!isRecord(value)) {\r\n      return;\r\n    }\r\n    Object.entries(value).forEach(([ key, val ]) => {\r\n      result[`${name}.${key}`] = val;\r\n    });\r\n  });\r\n\r\n  return result;\r\n};\r\n\r\n/**\r\n * Получает данные локализации из объекта и преобразует их в формат i18next resources.\r\n *\r\n * @param data{TLocaleSource} объект с локалями в формате { ns: { key: [lang1Value, lang2Value, ...] } }\r\n * @param type{string} тип ресурса (обычно \"translation\")\r\n * @param langKeys{string[]} массив кодов языков\r\n * @returns {TResources} объект ресурсов в формате i18next\r\n * @example\r\n * const data = {\r\n *   translation: {\r\n *     greeting: [\"Привет\", \"Hello\"],\r\n *     farewell: [\"Пока\", \"Bye\"]\r\n *   }\r\n * };\r\n * getResourcesFromObj({ data, langKeys: [\"ru\", \"en\"] });\r\n * // { ru: { translation: { translation: { greeting: \"Привет\", farewell: \"Пока\" } } }, ... }\r\n */\r\nconst getResourcesFromObj = ({\r\n  data = {},\r\n  type = \"translation\",\r\n  langKeys = constants.defaultLangKeys,\r\n}: {\r\n  data?: TLocaleSource;\r\n  type?: string;\r\n  langKeys?: string[];\r\n}): TResources => {\r\n  try {\r\n    const locales: TResources = {};\r\n\r\n    // Инициализируем структуру для каждого языка\r\n    langKeys.forEach((localeKey) => {\r\n      locales[localeKey] = { [type]: {} };\r\n    });\r\n\r\n    // Заполняем данные\r\n    Object.entries(data).forEach(([ ns, values ]) => {\r\n      if (!isRecord(values)) {\r\n        return;\r\n      }\r\n\r\n      Object.entries(values).forEach(([ key, value ]) => {\r\n        if (!Array.isArray(value)) {\r\n          return;\r\n        }\r\n\r\n        value.forEach((val, i) => {\r\n          const currentLang = langKeys[i];\r\n          if (!currentLang) {\r\n            return;\r\n          }\r\n          if (!isLocaleValue(val)) {\r\n            return;\r\n          }\r\n\r\n          // Получаем хранилище типа для текущего языка\r\n          const typeStorage = locales[currentLang][type];\r\n\r\n          // Получаем или создаём хранилище namespace\r\n          if (!typeStorage[ns]) {\r\n            typeStorage[ns] = {};\r\n          }\r\n\r\n          // Устанавливаем значение\r\n          typeStorage[ns][key] = val;\r\n        });\r\n      });\r\n    });\r\n\r\n    return locales;\r\n  } catch (e) {\r\n    console.error(`[Localisation] Error while parsing locales:`, e);\r\n    return {};\r\n  }\r\n};\r\n\r\n/**\r\n * Получает пользовательские атрибуты в виде объекта с одним уровнем вложенности.\r\n * Преобразует плоский объект с ключами-путями в обычный вложенный объект.\r\n *\r\n * @param obj{Record<string, unknown>} плоский объект с ключами-путями (например, { \"style.color\": \"red\" })\r\n * @returns {Record<string, unknown>} вложенный объект (например, { style: { color: \"red\" } })\r\n * @example\r\n * getUserAttrs({ \"style.color\": \"red\", \"style.fontSize\": 16 });\r\n * // { style: { color: \"red\", fontSize: 16 } }\r\n */\r\nconst getUserAttrs = (obj: Record<string, unknown>): Record<string, unknown> => {\r\n  if (!obj || Object.keys(obj).length === 0) {\r\n    return {};\r\n  }\r\n\r\n  const attrs = unflatten(obj, {\r\n    object: true,\r\n  });\r\n\r\n  return isRecord(attrs) ? attrs : {};\r\n};\r\n\r\n/**\r\n * Преобразует TLanguageResources в плоский объект с составными ключами.\r\n * Например, { new: { dynamic: \"value\" } } преобразуется в\r\n * { \"new.dynamic\": \"value\" }.\r\n * @returns {TFlatLocaleSource}\r\n */\r\nconst getFlattenLanguageResources = (\r\n  resources: TLanguageResources\r\n): TFlatLocaleSource => {\r\n  const result: TFlatLocaleSource = {};\r\n\r\n  Object.entries(resources).forEach(([ name, values ]) => {\r\n    if (!isRecord(values)) {\r\n      return;\r\n    }\r\n\r\n    Object.entries(values).forEach(([ key, value ]) => {\r\n      if (isLocaleValue(value)) {\r\n        result[`${name}.${key}`] = value;\r\n      }\r\n    });\r\n  });\r\n\r\n  return result;\r\n};\r\n\r\nexport type {\r\n  TFlatLocaleSource,\r\n  TLanguageResources,\r\n  TLocaleDictionary,\r\n  TLocaleSource,\r\n  TLocaleValue,\r\n  TResources,\r\n};\r\n\r\nexport {\r\n  getFlatResourceValues,\r\n  getFlattenLanguageResources,\r\n  getResourcesFromObj,\r\n  getUserAttrs,\r\n  isLocaleValue,\r\n  isRecord,\r\n};\r\n"],"names":["isRecord","value","Array","isArray","isLocaleValue","getFlatResourceValues","values","ns","result","namespacedValues","Object","entries","forEach","name","key","val","getResourcesFromObj","data","type","langKeys","constants","defaultLangKeys","locales","localeKey","i","currentLang","typeStorage","e","console","error","getUserAttrs","obj","keys","length","attrs","unflatten","object","getFlattenLanguageResources","resources"],"mappings":";;;;;;;;;;;;GAyBA,MAAMA,SAAYC,cACFA,QAAU,UAAYA,QAAU,OAASC,MAAMC,QAAQF;;;;GAOvE,MAAMG,cAAiBH,cACPA,QAAU,iBAAmBA,QAAU;;;;;;;;;;;;;;;;;GAoBvD,MAAMI,sBAAwB,CAACC,OAAwB,GAAIC,GAAa,MACtE,MAAMC,OAAkC,CAAA,EAExC,IAAKD,GACH,OAAOC,OAGT,MAAMC,iBAAmBH,OAAOC,IAChC,IAAKP,SAASS,kBACZ,OAAOD,OAGTE,OAAOC,QAAQF,kBAAkBG,QAAQ,EAAGC,KAAMZ,UAChD,IAAKD,SAASC,OACZ,OAEFS,OAAOC,QAAQV,OAAOW,QAAQ,EAAGE,IAAKC,QACpCP,OAAO,GAAGK,QAAQC,OAASC,QAI/B,OAAOP;;;;;;;;;;;;;;;;;GAoBT,MAAMQ,oBAAsB,EAC1BC,UAAO,CAAA,EACPC,UAAO,cACPC,kBAAWC,UAAUC,oBAMrB,IACE,MAAMC,QAAsB,CAAA;6CAG5BH;SAASP,QAASW,YAChBD,QAAQC,WAAa,CAAEL,CAACA,MAAO,CAAA;mBAIjCR;OAAOC,QAAQM,MAAML,QAAQ,EAAGL,GAAID,WAClC,IAAKN,SAASM,QACZ,OAGFI,OAAOC,QAAQL,QAAQM,QAAQ,EAAGE,IAAKb,UACrC,IAAKC,MAAMC,QAAQF,OACjB,OAGFA,MAAMW,QAAQ,CAACG,IAAKS,KAClB,MAAMC,YAAcN,SAASK,GAC7B,IAAKC,YACH,OAEF,IAAKrB,cAAcW,KACjB;6CAIF;MAAMW,YAAcJ,QAAQG,aAAaP;2CAGzC;IAAKQ,YAAYnB,IACfmB,YAAYnB,IAAM,CAAA;yBAIpBmB;YAAYnB,IAAIO,KAAOC,UAK7B,OAAOO,OACT,CAAE,MAAOK,GACPC,QAAQC,MAAM,8CAA+CF,GAC7D,MAAO,CAAA,CACT;;;;;;;;;;GAaF,MAAMG,aAAgBC,MACpB,IAAKA,KAAOrB,OAAOsB,KAAKD,KAAKE,SAAW,EACtC,MAAO,CAAA,EAGT,MAAMC,MAAQC,UAAUJ,IAAK,CAC3BK,OAAQ,OAGV,OAAOpC,SAASkC,OAASA,MAAQ,CAAA;;;;;;GASnC,MAAMG,4BACJC,YAEA,MAAM9B,OAA4B,CAAA,EAElCE,OAAOC,QAAQ2B,WAAW1B,QAAQ,EAAGC,KAAMP,WACzC,IAAKN,SAASM,QACZ,OAGFI,OAAOC,QAAQL,QAAQM,QAAQ,EAAGE,IAAKb,UACrC,GAAIG,cAAcH,OAChBO,OAAO,GAAGK,QAAQC,OAASb,UAKjC,OAAOO"}