@intlayer/core 7.0.9-canary.0 → 7.0.9-canary.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/README.md +2 -1
  2. package/dist/cjs/config/dist/esm/_virtual/rolldown_runtime.cjs +20 -0
  3. package/dist/cjs/config/dist/esm/_virtual/rolldown_runtime.cjs.map +1 -0
  4. package/dist/cjs/config/dist/esm/built.cjs +8 -0
  5. package/dist/cjs/config/dist/esm/built.cjs.map +1 -0
  6. package/dist/cjs/config/dist/esm/configFile/buildConfigurationFields.cjs +119 -0
  7. package/dist/cjs/config/dist/esm/configFile/buildConfigurationFields.cjs.map +1 -0
  8. package/dist/cjs/config/dist/esm/configFile/getConfiguration.cjs +69 -0
  9. package/dist/cjs/config/dist/esm/configFile/getConfiguration.cjs.map +1 -0
  10. package/dist/cjs/config/dist/esm/configFile/loadConfigurationFile.cjs +26 -0
  11. package/dist/cjs/config/dist/esm/configFile/loadConfigurationFile.cjs.map +1 -0
  12. package/dist/cjs/config/dist/esm/configFile/searchConfigurationFile.cjs +51 -0
  13. package/dist/cjs/config/dist/esm/configFile/searchConfigurationFile.cjs.map +1 -0
  14. package/dist/cjs/config/dist/esm/defaultValues/build.cjs +24 -0
  15. package/dist/cjs/config/dist/esm/defaultValues/build.cjs.map +1 -0
  16. package/dist/cjs/config/dist/esm/defaultValues/content.cjs +78 -0
  17. package/dist/cjs/config/dist/esm/defaultValues/content.cjs.map +1 -0
  18. package/dist/cjs/config/dist/esm/defaultValues/dictionary.cjs +7 -0
  19. package/dist/cjs/config/dist/esm/defaultValues/dictionary.cjs.map +1 -0
  20. package/dist/cjs/config/dist/esm/defaultValues/editor.cjs +36 -0
  21. package/dist/cjs/config/dist/esm/defaultValues/editor.cjs.map +1 -0
  22. package/dist/cjs/config/dist/esm/defaultValues/index.cjs +21 -0
  23. package/dist/cjs/config/dist/esm/defaultValues/index.cjs.map +1 -0
  24. package/dist/cjs/config/dist/esm/defaultValues/internationalization.cjs +22 -0
  25. package/dist/cjs/config/dist/esm/defaultValues/internationalization.cjs.map +1 -0
  26. package/dist/cjs/config/dist/esm/defaultValues/log.cjs +16 -0
  27. package/dist/cjs/config/dist/esm/defaultValues/log.cjs.map +1 -0
  28. package/dist/cjs/config/dist/esm/defaultValues/routing.cjs +26 -0
  29. package/dist/cjs/config/dist/esm/defaultValues/routing.cjs.map +1 -0
  30. package/dist/cjs/config/dist/esm/loadEnvFile.cjs +26 -0
  31. package/dist/cjs/config/dist/esm/loadEnvFile.cjs.map +1 -0
  32. package/dist/cjs/config/dist/esm/loadExternalFile/bundleFile.cjs +23 -0
  33. package/dist/cjs/config/dist/esm/loadExternalFile/bundleFile.cjs.map +1 -0
  34. package/dist/cjs/config/dist/esm/loadExternalFile/loadExternalFile.cjs +47 -0
  35. package/dist/cjs/config/dist/esm/loadExternalFile/loadExternalFile.cjs.map +1 -0
  36. package/dist/cjs/config/dist/esm/loadExternalFile/parseFileContent.cjs +65 -0
  37. package/dist/cjs/config/dist/esm/loadExternalFile/parseFileContent.cjs.map +1 -0
  38. package/dist/cjs/config/dist/esm/loadExternalFile/transpileTSToMJS.cjs +45 -0
  39. package/dist/cjs/config/dist/esm/loadExternalFile/transpileTSToMJS.cjs.map +1 -0
  40. package/dist/cjs/config/dist/esm/logger.cjs +65 -0
  41. package/dist/cjs/config/dist/esm/logger.cjs.map +1 -0
  42. package/dist/cjs/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.cjs +15 -0
  43. package/dist/cjs/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.cjs.map +1 -0
  44. package/dist/cjs/config/dist/esm/types/dist/esm/locales.cjs +1128 -0
  45. package/dist/cjs/config/dist/esm/types/dist/esm/locales.cjs.map +1 -0
  46. package/dist/cjs/config/dist/esm/utils/ESMxCJSHelpers.cjs +27 -0
  47. package/dist/cjs/config/dist/esm/utils/ESMxCJSHelpers.cjs.map +1 -0
  48. package/dist/cjs/config/dist/esm/utils/cache.cjs +261 -0
  49. package/dist/cjs/config/dist/esm/utils/cache.cjs.map +1 -0
  50. package/dist/cjs/config/dist/esm/utils/clearModuleCache.cjs +26 -0
  51. package/dist/cjs/config/dist/esm/utils/clearModuleCache.cjs.map +1 -0
  52. package/dist/cjs/config/dist/esm/utils/getPackageJsonPath.cjs +34 -0
  53. package/dist/cjs/config/dist/esm/utils/getPackageJsonPath.cjs.map +1 -0
  54. package/dist/cjs/config/dist/esm/utils/normalizePath.cjs +17 -0
  55. package/dist/cjs/config/dist/esm/utils/normalizePath.cjs.map +1 -0
  56. package/dist/cjs/dictionaries-entry/dist/esm/_virtual/rolldown_runtime.cjs +10 -0
  57. package/dist/cjs/dictionaries-entry/dist/esm/_virtual/rolldown_runtime.cjs.map +1 -0
  58. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/_virtual/rolldown_runtime.cjs +11 -0
  59. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/_virtual/rolldown_runtime.cjs.map +1 -0
  60. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/built.cjs +8 -0
  61. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/built.cjs.map +1 -0
  62. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/buildConfigurationFields.cjs +119 -0
  63. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/buildConfigurationFields.cjs.map +1 -0
  64. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/getConfiguration.cjs +69 -0
  65. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/getConfiguration.cjs.map +1 -0
  66. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/loadConfigurationFile.cjs +26 -0
  67. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/loadConfigurationFile.cjs.map +1 -0
  68. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/searchConfigurationFile.cjs +51 -0
  69. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/configFile/searchConfigurationFile.cjs.map +1 -0
  70. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/build.cjs +15 -0
  71. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/build.cjs.map +1 -0
  72. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/content.cjs +54 -0
  73. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/content.cjs.map +1 -0
  74. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/dictionary.cjs +7 -0
  75. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/dictionary.cjs.map +1 -0
  76. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/editor.cjs +23 -0
  77. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/editor.cjs.map +1 -0
  78. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/internationalization.cjs +14 -0
  79. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/internationalization.cjs.map +1 -0
  80. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/log.cjs +10 -0
  81. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/log.cjs.map +1 -0
  82. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/routing.cjs +11 -0
  83. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/routing.cjs.map +1 -0
  84. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadEnvFile.cjs +26 -0
  85. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadEnvFile.cjs.map +1 -0
  86. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/bundleFile.cjs +23 -0
  87. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/bundleFile.cjs.map +1 -0
  88. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/loadExternalFile.cjs +47 -0
  89. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/loadExternalFile.cjs.map +1 -0
  90. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/parseFileContent.cjs +65 -0
  91. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/parseFileContent.cjs.map +1 -0
  92. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/transpileTSToMJS.cjs +45 -0
  93. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/transpileTSToMJS.cjs.map +1 -0
  94. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/logger.cjs +47 -0
  95. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/logger.cjs.map +1 -0
  96. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.cjs +15 -0
  97. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.cjs.map +1 -0
  98. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/locales.cjs +1128 -0
  99. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/locales.cjs.map +1 -0
  100. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/ESMxCJSHelpers.cjs +27 -0
  101. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/ESMxCJSHelpers.cjs.map +1 -0
  102. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/cache.cjs +261 -0
  103. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/cache.cjs.map +1 -0
  104. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/getPackageJsonPath.cjs +34 -0
  105. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/getPackageJsonPath.cjs.map +1 -0
  106. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/normalizePath.cjs +17 -0
  107. package/dist/cjs/dictionaries-entry/dist/esm/config/dist/esm/utils/normalizePath.cjs.map +1 -0
  108. package/dist/cjs/dictionaries-entry/dist/esm/index.cjs +27 -0
  109. package/dist/cjs/dictionaries-entry/dist/esm/index.cjs.map +1 -0
  110. package/dist/cjs/types/dist/esm/_virtual/rolldown_runtime.cjs +15 -0
  111. package/dist/cjs/types/dist/esm/_virtual/rolldown_runtime.cjs.map +1 -0
  112. package/dist/cjs/types/dist/esm/locales.cjs +1128 -0
  113. package/dist/cjs/types/dist/esm/locales.cjs.map +1 -0
  114. package/dist/cjs/types/dist/esm/nodeType.cjs +31 -0
  115. package/dist/cjs/types/dist/esm/nodeType.cjs.map +1 -0
  116. package/dist/esm/_virtual/rolldown_runtime.mjs +8 -0
  117. package/dist/esm/config/dist/esm/_virtual/rolldown_runtime.mjs +20 -0
  118. package/dist/esm/config/dist/esm/_virtual/rolldown_runtime.mjs.map +1 -0
  119. package/dist/esm/config/dist/esm/built.mjs +8 -0
  120. package/dist/esm/config/dist/esm/built.mjs.map +1 -0
  121. package/dist/esm/config/dist/esm/configFile/buildConfigurationFields.mjs +118 -0
  122. package/dist/esm/config/dist/esm/configFile/buildConfigurationFields.mjs.map +1 -0
  123. package/dist/esm/config/dist/esm/configFile/getConfiguration.mjs +67 -0
  124. package/dist/esm/config/dist/esm/configFile/getConfiguration.mjs.map +1 -0
  125. package/dist/esm/config/dist/esm/configFile/loadConfigurationFile.mjs +26 -0
  126. package/dist/esm/config/dist/esm/configFile/loadConfigurationFile.mjs.map +1 -0
  127. package/dist/esm/config/dist/esm/configFile/searchConfigurationFile.mjs +50 -0
  128. package/dist/esm/config/dist/esm/configFile/searchConfigurationFile.mjs.map +1 -0
  129. package/dist/esm/config/dist/esm/defaultValues/build.mjs +19 -0
  130. package/dist/esm/config/dist/esm/defaultValues/build.mjs.map +1 -0
  131. package/dist/esm/config/dist/esm/defaultValues/content.mjs +64 -0
  132. package/dist/esm/config/dist/esm/defaultValues/content.mjs.map +1 -0
  133. package/dist/esm/config/dist/esm/defaultValues/dictionary.mjs +6 -0
  134. package/dist/esm/config/dist/esm/defaultValues/dictionary.mjs.map +1 -0
  135. package/dist/esm/config/dist/esm/defaultValues/editor.mjs +27 -0
  136. package/dist/esm/config/dist/esm/defaultValues/editor.mjs.map +1 -0
  137. package/dist/esm/config/dist/esm/defaultValues/index.mjs +21 -0
  138. package/dist/esm/config/dist/esm/defaultValues/index.mjs.map +1 -0
  139. package/dist/esm/config/dist/esm/defaultValues/internationalization.mjs +18 -0
  140. package/dist/esm/config/dist/esm/defaultValues/internationalization.mjs.map +1 -0
  141. package/dist/esm/config/dist/esm/defaultValues/log.mjs +14 -0
  142. package/dist/esm/config/dist/esm/defaultValues/log.mjs.map +1 -0
  143. package/dist/esm/config/dist/esm/defaultValues/routing.mjs +23 -0
  144. package/dist/esm/config/dist/esm/defaultValues/routing.mjs.map +1 -0
  145. package/dist/esm/config/dist/esm/loadEnvFile.mjs +24 -0
  146. package/dist/esm/config/dist/esm/loadEnvFile.mjs.map +1 -0
  147. package/dist/esm/config/dist/esm/loadExternalFile/bundleFile.mjs +23 -0
  148. package/dist/esm/config/dist/esm/loadExternalFile/bundleFile.mjs.map +1 -0
  149. package/dist/esm/config/dist/esm/loadExternalFile/loadExternalFile.mjs +47 -0
  150. package/dist/esm/config/dist/esm/loadExternalFile/loadExternalFile.mjs.map +1 -0
  151. package/dist/esm/config/dist/esm/loadExternalFile/parseFileContent.mjs +63 -0
  152. package/dist/esm/config/dist/esm/loadExternalFile/parseFileContent.mjs.map +1 -0
  153. package/dist/esm/config/dist/esm/loadExternalFile/transpileTSToMJS.mjs +44 -0
  154. package/dist/esm/config/dist/esm/loadExternalFile/transpileTSToMJS.mjs.map +1 -0
  155. package/dist/esm/config/dist/esm/logger.mjs +59 -0
  156. package/dist/esm/config/dist/esm/logger.mjs.map +1 -0
  157. package/dist/esm/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.mjs +14 -0
  158. package/dist/esm/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.mjs.map +1 -0
  159. package/dist/esm/config/dist/esm/types/dist/esm/locales.mjs +1128 -0
  160. package/dist/esm/config/dist/esm/types/dist/esm/locales.mjs.map +1 -0
  161. package/dist/esm/config/dist/esm/utils/ESMxCJSHelpers.mjs +25 -0
  162. package/dist/esm/config/dist/esm/utils/ESMxCJSHelpers.mjs.map +1 -0
  163. package/dist/esm/config/dist/esm/utils/cache.mjs +263 -0
  164. package/dist/esm/config/dist/esm/utils/cache.mjs.map +1 -0
  165. package/dist/esm/config/dist/esm/utils/getPackageJsonPath.mjs +33 -0
  166. package/dist/esm/config/dist/esm/utils/getPackageJsonPath.mjs.map +1 -0
  167. package/dist/esm/config/dist/esm/utils/normalizePath.mjs +16 -0
  168. package/dist/esm/config/dist/esm/utils/normalizePath.mjs.map +1 -0
  169. package/dist/esm/dictionaries-entry/dist/esm/_virtual/rolldown_runtime.mjs +11 -0
  170. package/dist/esm/dictionaries-entry/dist/esm/_virtual/rolldown_runtime.mjs.map +1 -0
  171. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/_virtual/rolldown_runtime.mjs +11 -0
  172. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/_virtual/rolldown_runtime.mjs.map +1 -0
  173. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/built.mjs +8 -0
  174. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/built.mjs.map +1 -0
  175. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/buildConfigurationFields.mjs +118 -0
  176. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/buildConfigurationFields.mjs.map +1 -0
  177. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/getConfiguration.mjs +67 -0
  178. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/getConfiguration.mjs.map +1 -0
  179. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/loadConfigurationFile.mjs +26 -0
  180. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/loadConfigurationFile.mjs.map +1 -0
  181. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/searchConfigurationFile.mjs +50 -0
  182. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/configFile/searchConfigurationFile.mjs.map +1 -0
  183. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/build.mjs +10 -0
  184. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/build.mjs.map +1 -0
  185. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/content.mjs +40 -0
  186. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/content.mjs.map +1 -0
  187. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/dictionary.mjs +6 -0
  188. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/dictionary.mjs.map +1 -0
  189. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/editor.mjs +14 -0
  190. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/editor.mjs.map +1 -0
  191. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/internationalization.mjs +11 -0
  192. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/internationalization.mjs.map +1 -0
  193. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/log.mjs +9 -0
  194. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/log.mjs.map +1 -0
  195. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/routing.mjs +8 -0
  196. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/defaultValues/routing.mjs.map +1 -0
  197. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadEnvFile.mjs +24 -0
  198. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadEnvFile.mjs.map +1 -0
  199. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/bundleFile.mjs +23 -0
  200. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/bundleFile.mjs.map +1 -0
  201. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/loadExternalFile.mjs +47 -0
  202. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/loadExternalFile.mjs.map +1 -0
  203. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/parseFileContent.mjs +63 -0
  204. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/parseFileContent.mjs.map +1 -0
  205. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/transpileTSToMJS.mjs +44 -0
  206. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/loadExternalFile/transpileTSToMJS.mjs.map +1 -0
  207. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/logger.mjs +45 -0
  208. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/logger.mjs.map +1 -0
  209. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.mjs +14 -0
  210. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/_virtual/rolldown_runtime.mjs.map +1 -0
  211. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/locales.mjs +1128 -0
  212. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/types/dist/esm/locales.mjs.map +1 -0
  213. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/ESMxCJSHelpers.mjs +25 -0
  214. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/ESMxCJSHelpers.mjs.map +1 -0
  215. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/cache.mjs +263 -0
  216. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/cache.mjs.map +1 -0
  217. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/getPackageJsonPath.mjs +33 -0
  218. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/getPackageJsonPath.mjs.map +1 -0
  219. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/normalizePath.mjs +16 -0
  220. package/dist/esm/dictionaries-entry/dist/esm/config/dist/esm/utils/normalizePath.mjs.map +1 -0
  221. package/dist/esm/dictionaries-entry/dist/esm/index.mjs +25 -0
  222. package/dist/esm/dictionaries-entry/dist/esm/index.mjs.map +1 -0
  223. package/dist/esm/types/dist/esm/_virtual/rolldown_runtime.mjs +14 -0
  224. package/dist/esm/types/dist/esm/_virtual/rolldown_runtime.mjs.map +1 -0
  225. package/dist/esm/types/dist/esm/locales.mjs +1128 -0
  226. package/dist/esm/types/dist/esm/locales.mjs.map +1 -0
  227. package/dist/esm/types/dist/esm/nodeType.mjs +29 -0
  228. package/dist/esm/types/dist/esm/nodeType.mjs.map +1 -0
  229. package/dist/index.d.mts +1323 -0
  230. package/dist/index.mjs +3348 -0
  231. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts +7 -7
  232. package/dist/types/deepTransformPlugins/getFilterMissingTranslationsContent.d.ts.map +1 -1
  233. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts +7 -7
  234. package/dist/types/deepTransformPlugins/getFilterTranslationsOnlyContent.d.ts.map +1 -1
  235. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts +7 -7
  236. package/dist/types/deepTransformPlugins/getFilteredLocalesContent.d.ts.map +1 -1
  237. package/dist/types/dictionaryManipulator/orderDictionaries.d.ts +2 -2
  238. package/dist/types/interpreter/getContent/plugins.d.ts.map +1 -1
  239. package/dist/types/transpiler/translation/translation.d.ts +1 -1
  240. package/dist/types/transpiler/translation/translation.d.ts.map +1 -1
  241. package/package.json +20 -17
  242. package/dist/cjs/dictionaryManipulator/getUnmergedDictionaryByKeyPath.cjs +0 -20
  243. package/dist/cjs/dictionaryManipulator/getUnmergedDictionaryByKeyPath.cjs.map +0 -1
  244. package/dist/esm/dictionaryManipulator/getUnmergedDictionaryByKeyPath.mjs +0 -17
  245. package/dist/esm/dictionaryManipulator/getUnmergedDictionaryByKeyPath.mjs.map +0 -1
  246. package/dist/types/deepTransformPlugins/index.d.ts.map +0 -1
  247. package/dist/types/dictionaryManipulator/getUnmergedDictionaryByKeyPath.d.ts +0 -9
  248. package/dist/types/dictionaryManipulator/getUnmergedDictionaryByKeyPath.d.ts.map +0 -1
  249. package/dist/types/dictionaryManipulator/index.d.ts.map +0 -1
  250. package/dist/types/formatters/index.d.ts.map +0 -1
  251. package/dist/types/index.d.ts.map +0 -1
  252. package/dist/types/interpreter/getContent/index.d.ts.map +0 -1
  253. package/dist/types/interpreter/getIntlayerAsync.d.ts +0 -13
  254. package/dist/types/interpreter/getIntlayerAsync.d.ts.map +0 -1
  255. package/dist/types/interpreter/index.d.ts.map +0 -1
  256. package/dist/types/localization/index.d.ts.map +0 -1
  257. package/dist/types/localization/localeList.d.ts +0 -3
  258. package/dist/types/localization/localeList.d.ts.map +0 -1
  259. package/dist/types/transpiler/condition/index.d.ts.map +0 -1
  260. package/dist/types/transpiler/enumeration/index.d.ts.map +0 -1
  261. package/dist/types/transpiler/file/index.d.ts.map +0 -1
  262. package/dist/types/transpiler/gender/index.d.ts.map +0 -1
  263. package/dist/types/transpiler/index.d.ts.map +0 -1
  264. package/dist/types/transpiler/insertion/index.d.ts.map +0 -1
  265. package/dist/types/transpiler/markdown/index.d.ts.map +0 -1
  266. package/dist/types/transpiler/nesting/index.d.ts.map +0 -1
  267. package/dist/types/transpiler/translation/index.d.ts.map +0 -1
  268. package/dist/types/types/dictionary.d.ts +0 -307
  269. package/dist/types/types/dictionary.d.ts.map +0 -1
  270. package/dist/types/types/index.d.ts +0 -5
  271. package/dist/types/types/index.d.ts.map +0 -1
  272. package/dist/types/types/intlayer.d.ts +0 -5
  273. package/dist/types/types/intlayer.d.ts.map +0 -1
  274. package/dist/types/types/keyPath.d.ts +0 -47
  275. package/dist/types/types/keyPath.d.ts.map +0 -1
  276. package/dist/types/types/nodeType.d.ts +0 -30
  277. package/dist/types/types/nodeType.d.ts.map +0 -1
  278. package/dist/types/types/translation.d.ts +0 -25
  279. package/dist/types/types/translation.d.ts.map +0 -1
package/dist/index.mjs ADDED
@@ -0,0 +1,3348 @@
1
+ import { Locales, NodeType, formatNodeType } from "@intlayer/types";
2
+ import configuration from "@intlayer/config/built";
3
+ import { getDictionaries } from "@intlayer/dictionaries-entry";
4
+ import { DefaultValues, colorizeKey, getAppLogger } from "@intlayer/config/client";
5
+
6
+ //#region src/interpreter/getCondition.ts
7
+ /**
8
+ * Allow to pick a content based on a condition.
9
+ *
10
+ * Usage:
11
+ *
12
+ * ```ts
13
+ * const content = getCondition({
14
+ * 'true': 'The condition is validated',
15
+ * 'false': 'The condition is not validated',
16
+ * }, true);
17
+ * // 'The condition is validated'
18
+ * ```
19
+ *
20
+ * The last key provided will be used as the fallback value.
21
+ *
22
+ * ```ts
23
+ * const content = getCondition({
24
+ * 'false': 'The condition is not validated',
25
+ * 'true': 'The condition is validated',
26
+ * }, undefined);
27
+ * // 'The condition is validated'
28
+ */
29
+ const getCondition = (conditionContent, state) => {
30
+ const stateList = Object.keys(conditionContent);
31
+ const fallbackState = stateList[stateList.length - 1];
32
+ return conditionContent[`${state}`] ?? conditionContent.fallback ?? conditionContent[fallbackState];
33
+ };
34
+
35
+ //#endregion
36
+ //#region src/interpreter/getContent/deepTransform.ts
37
+ /**
38
+ * Recursively traverses a node (object/array/primitive).
39
+ * Applies the *first* plugin that can transform a node, then stops descending further.
40
+ * If no plugin transforms it, it recurses into its children.
41
+ */
42
+ const deepTransformNode = (node, props) => {
43
+ for (const plugin of props.plugins ?? []) if (plugin.canHandle(node)) return plugin.transform(node, props, (node$1, props$1) => deepTransformNode(node$1, props$1));
44
+ if (node === null || typeof node !== "object") return node;
45
+ if (Array.isArray(node)) return node.map((child, index) => {
46
+ return deepTransformNode(child, {
47
+ ...props,
48
+ children: child,
49
+ keyPath: [...props.keyPath, {
50
+ type: NodeType.Array,
51
+ key: index
52
+ }]
53
+ });
54
+ });
55
+ const result = {};
56
+ for (const key in node) {
57
+ const childProps = {
58
+ ...props,
59
+ children: node[key],
60
+ keyPath: [...props.keyPath, {
61
+ type: NodeType.Object,
62
+ key
63
+ }]
64
+ };
65
+ result[key] = deepTransformNode(node[key], childProps);
66
+ }
67
+ return result;
68
+ };
69
+
70
+ //#endregion
71
+ //#region src/interpreter/getEnumeration.ts
72
+ /**
73
+ * Find the matching condition for a quantity.
74
+ *
75
+ * Usage:
76
+ *
77
+ * ```ts
78
+ * const key = findMatchingCondition({
79
+ * '<=-2.3': 'You have less than -2.3',
80
+ * '<1': 'You have less than one',
81
+ * '2': 'You have two',
82
+ * '>=3': 'You have three or more',
83
+ * }, 2);
84
+ * // '2'
85
+ * ```
86
+ *
87
+ * The order of the keys will define the priority of the content.
88
+ *
89
+ * ```ts
90
+ * const key = findMatchingCondition({
91
+ * '<4': 'You have less than four',
92
+ * '2': 'You have two',
93
+ * }, 2);
94
+ * // '<4'
95
+ * ```
96
+ *
97
+ * If no keys match, the default key is '1'.
98
+ */
99
+ const findMatchingCondition = (enumerationContent, quantity) => {
100
+ const numericKeys = Object.keys(enumerationContent);
101
+ for (const key of numericKeys) {
102
+ const isEqual = !key.startsWith(">") && !key.startsWith("<") && !key.startsWith("=") && parseFloat(key) === quantity || key.startsWith("=") && parseFloat(key.slice(1)) === quantity;
103
+ const isSuperior = key.startsWith(">") && quantity > parseFloat(key.slice(1));
104
+ const isSuperiorOrEqual = key.startsWith(">=") && quantity >= parseFloat(key.slice(2));
105
+ const isInferior = key.startsWith("<") && quantity < parseFloat(key.slice(1));
106
+ const isInferiorOrEqual = key.startsWith("<=") && quantity <= parseFloat(key.slice(2));
107
+ if (isEqual || isSuperior || isSuperiorOrEqual || isInferior || isInferiorOrEqual) return key;
108
+ }
109
+ };
110
+ /**
111
+ * Allow to pick a content based on a quantity.
112
+ *
113
+ * Usage:
114
+ *
115
+ * ```ts
116
+ * const content = getEnumeration({
117
+ * '<=-2.3': 'You have less than -2.3',
118
+ * '<1': 'You have less than one',
119
+ * '2': 'You have two',
120
+ * '>=3': 'You have three or more',
121
+ * }, 2);
122
+ * // 'You have two'
123
+ * ```
124
+ *
125
+ * The order of the keys will define the priority of the content.
126
+ *
127
+ * ```ts
128
+ * const content = getEnumeration({
129
+ * '<4': 'You have less than four',
130
+ * '2': 'You have two',
131
+ * }, 2);
132
+ * // 'You have less than four'
133
+ * ```
134
+ *
135
+ */
136
+ const getEnumeration = (enumerationContent, quantity) => {
137
+ return enumerationContent[findMatchingCondition(enumerationContent, quantity) ?? "fallback"];
138
+ };
139
+
140
+ //#endregion
141
+ //#region src/interpreter/getGender.ts
142
+ const getGenderEntry = (gender$1) => {
143
+ if (gender$1 === "m" || gender$1 === "male") return "male";
144
+ if (gender$1 === "f" || gender$1 === "female") return "female";
145
+ return "fallback";
146
+ };
147
+ /**
148
+ * Allow to pick a content based on a gender.
149
+ *
150
+ * Usage:
151
+ *
152
+ * ```ts
153
+ * const content = getGender({
154
+ * 'true': 'The gender is validated',
155
+ * 'false': 'The gender is not validated',
156
+ * }, true);
157
+ * // 'The gender is validated'
158
+ * ```
159
+ *
160
+ * The last key provided will be used as the fallback value.
161
+ *
162
+ * ```ts
163
+ * const content = getGender({
164
+ * 'false': 'The gender is not validated',
165
+ * 'true': 'The gender is validated',
166
+ * }, undefined);
167
+ * // 'The gender is validated'
168
+ */
169
+ const getGender = (genderContent, gender$1) => {
170
+ const stateList = Object.keys(genderContent);
171
+ const fallbackState = stateList[stateList.length - 1];
172
+ return genderContent[getGenderEntry(gender$1)] ?? genderContent.fallback ?? genderContent[fallbackState];
173
+ };
174
+
175
+ //#endregion
176
+ //#region src/interpreter/getInsertion.ts
177
+ /**
178
+ * Allow to insert values in a string.
179
+ *
180
+ * Usage:
181
+ *
182
+ * ```ts
183
+ * const content = getInsertion('Hello {{name}}!', {
184
+ * name: 'John',
185
+ * });
186
+ * // 'Hello John!'
187
+ * ```
188
+ *
189
+ */
190
+ const getInsertion = (content, values) => content.replace(/\{\{(.*?)\}\}/g, (_, key) => (values[key] ?? "").toString());
191
+
192
+ //#endregion
193
+ //#region src/interpreter/getDictionary.ts
194
+ /**
195
+ * Transforms a dictionary in a single pass, applying each plugin as needed.
196
+ *
197
+ * @param dictionary The dictionary to transform.
198
+ * @param locale The locale to use if your transformers need it (e.g. for translations).
199
+ * @param additionalPlugins An array of NodeTransformer that define how to transform recognized nodes.
200
+ * If omitted, we’ll use a default set of plugins.
201
+ */
202
+ const getDictionary = (dictionary, locale, plugins) => {
203
+ const props = {
204
+ dictionaryKey: dictionary.key,
205
+ dictionaryPath: dictionary.filePath,
206
+ keyPath: [],
207
+ plugins
208
+ };
209
+ return getContent(dictionary.content, props, locale);
210
+ };
211
+
212
+ //#endregion
213
+ //#region src/interpreter/getIntlayer.ts
214
+ const getIntlayer = (key, locale, plugins) => {
215
+ const dictionaries = getDictionaries();
216
+ const dictionary = dictionaries[key];
217
+ if (!dictionary) throw new Error(`Dictionary ${key} not found`, dictionaries);
218
+ return getDictionary(dictionary, locale, plugins);
219
+ };
220
+
221
+ //#endregion
222
+ //#region src/interpreter/getNesting.ts
223
+ /**
224
+ * Allow to extract the content of another dictionary.
225
+ *
226
+ * Usage:
227
+ * ```ts
228
+ * const content = getNesting("dictionaryKey", "path.to.content");
229
+ * // 'Example content'
230
+ * ```
231
+ */
232
+ const getNesting = (dictionaryKey, path, props) => {
233
+ const dictionary = getIntlayer(dictionaryKey, props === null || props === void 0 ? void 0 : props.locale, props === null || props === void 0 ? void 0 : props.plugins);
234
+ if (typeof path === "string") {
235
+ const pathArray = path.split(".");
236
+ let current = dictionary;
237
+ for (const key of pathArray) {
238
+ current = current === null || current === void 0 ? void 0 : current[key];
239
+ if (current === void 0) return dictionary;
240
+ }
241
+ return current;
242
+ }
243
+ return dictionary;
244
+ };
245
+
246
+ //#endregion
247
+ //#region src/interpreter/getTranslation.ts
248
+ /**
249
+ *
250
+ * Allow to pick a content based on a locale.
251
+ * If not locale found, it will return the content related to the default locale.
252
+ *
253
+ * Return either the content editor, or the content itself depending on the configuration.
254
+ *
255
+ * Usage:
256
+ *
257
+ * ```ts
258
+ * const content = getTranslation<string>({
259
+ * en: 'Hello',
260
+ * fr: 'Bonjour',
261
+ * }, 'fr');
262
+ * // 'Bonjour'
263
+ * ```
264
+ *
265
+ * Using TypeScript:
266
+ * - this function will require each locale to be defined if defined in the project configuration.
267
+ * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
268
+ */
269
+ const getTranslation = (languageContent, locale, fallback) => {
270
+ let result = languageContent[locale];
271
+ if (fallback && !result) result = languageContent[fallback];
272
+ return result;
273
+ };
274
+
275
+ //#endregion
276
+ //#region src/interpreter/getContent/plugins.ts
277
+ /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
278
+ const translationPlugin = (locale, fallback) => ({
279
+ id: "translation-plugin",
280
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation,
281
+ transform: (node, props, deepTransformNode$1) => {
282
+ const result = structuredClone(node[NodeType.Translation]);
283
+ for (const key in result) {
284
+ const childProps = {
285
+ ...props,
286
+ children: result[key],
287
+ keyPath: [...props.keyPath, {
288
+ type: NodeType.Translation,
289
+ key
290
+ }]
291
+ };
292
+ result[key] = deepTransformNode$1(result[key], childProps);
293
+ }
294
+ return getTranslation(result, locale, fallback);
295
+ }
296
+ });
297
+ /** Enumeration plugin. Replaces node with a function that takes quantity => string. */
298
+ const enumerationPlugin = {
299
+ id: "enumeration-plugin",
300
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Enumeration,
301
+ transform: (node, props, deepTransformNode$1) => {
302
+ const result = structuredClone(node[NodeType.Enumeration]);
303
+ for (const key in result) {
304
+ const child = result[key];
305
+ result[key] = deepTransformNode$1(child, {
306
+ ...props,
307
+ children: child,
308
+ keyPath: [...props.keyPath, {
309
+ type: NodeType.Enumeration,
310
+ key
311
+ }]
312
+ });
313
+ }
314
+ return (quantity) => getEnumeration(result, quantity);
315
+ }
316
+ };
317
+ /** Condition plugin. Replaces node with a function that takes boolean => string. */
318
+ const conditionPlugin = {
319
+ id: "condition-plugin",
320
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Condition,
321
+ transform: (node, props, deepTransformNode$1) => {
322
+ const result = structuredClone(node[NodeType.Condition]);
323
+ for (const key in result) {
324
+ const child = result[key];
325
+ result[key] = deepTransformNode$1(child, {
326
+ ...props,
327
+ children: child,
328
+ keyPath: [...props.keyPath, {
329
+ type: NodeType.Condition,
330
+ key
331
+ }]
332
+ });
333
+ }
334
+ return (value) => getCondition(result, value);
335
+ }
336
+ };
337
+ /** Gender plugin. Replaces node with a function that takes gender => string. */
338
+ const genderPlugin = {
339
+ id: "gender-plugin",
340
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Gender,
341
+ transform: (node, props, deepTransformNode$1) => {
342
+ const result = structuredClone(node[NodeType.Gender]);
343
+ for (const key in result) {
344
+ const child = result[key];
345
+ result[key] = deepTransformNode$1(child, {
346
+ ...props,
347
+ children: child,
348
+ keyPath: [...props.keyPath, {
349
+ type: NodeType.Gender,
350
+ key
351
+ }]
352
+ });
353
+ }
354
+ return (value) => getGender(result, value);
355
+ }
356
+ };
357
+ const insertionPlugin = {
358
+ id: "insertion-plugin",
359
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Insertion,
360
+ transform: (node, props, deepTransformNode$1) => {
361
+ const newKeyPath = [...props.keyPath, { type: NodeType.Insertion }];
362
+ const children = node[NodeType.Insertion];
363
+ /** Insertion string plugin. Replaces string node with a component that render the insertion. */
364
+ const insertionStringPlugin = {
365
+ id: "insertion-string-plugin",
366
+ canHandle: (node$1) => typeof node$1 === "string",
367
+ transform: (node$1, subProps, deepTransformNode$2) => {
368
+ const transformedResult = deepTransformNode$2(node$1, {
369
+ ...subProps,
370
+ children: node$1,
371
+ plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "intlayer-node-plugin")]
372
+ });
373
+ return (values) => {
374
+ const children$1 = getInsertion(transformedResult, values);
375
+ return deepTransformNode$2(children$1, {
376
+ ...subProps,
377
+ plugins: props.plugins,
378
+ children: children$1
379
+ });
380
+ };
381
+ }
382
+ };
383
+ return deepTransformNode$1(children, {
384
+ ...props,
385
+ children,
386
+ keyPath: newKeyPath,
387
+ plugins: [insertionStringPlugin, ...props.plugins ?? []]
388
+ });
389
+ }
390
+ };
391
+ /** Nested plugin. Replaces node with the result of `getNesting`. */
392
+ const nestedPlugin = {
393
+ id: "nested-plugin",
394
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Nested,
395
+ transform: (node, props) => getNesting(node.nested.dictionaryKey, node.nested.path, props)
396
+ };
397
+ /** File plugin. Replaces node with the result of `getNesting`. */
398
+ const filePlugin = {
399
+ id: "file-plugin",
400
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.File,
401
+ transform: (node, props, deepTransform) => deepTransform(node.content, {
402
+ ...props,
403
+ children: node.content
404
+ })
405
+ };
406
+
407
+ //#endregion
408
+ //#region src/interpreter/getContent/getContent.ts
409
+ /**
410
+ * Transforms a node in a single pass, applying each plugin as needed.
411
+ *
412
+ * @param node The node to transform.
413
+ * @param locale The locale to use if your transformers need it (e.g. for translations).
414
+ */
415
+ const getContent = (node, nodeProps, locale) => {
416
+ var _configuration$intern;
417
+ const defaultLocale = configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale;
418
+ const plugins = [
419
+ insertionPlugin,
420
+ translationPlugin(locale ?? defaultLocale, defaultLocale),
421
+ enumerationPlugin,
422
+ conditionPlugin,
423
+ nestedPlugin,
424
+ filePlugin,
425
+ ...nodeProps.plugins ?? []
426
+ ];
427
+ return deepTransformNode(node, {
428
+ ...nodeProps,
429
+ plugins
430
+ });
431
+ };
432
+
433
+ //#endregion
434
+ //#region src/deepTransformPlugins/getFilteredLocalesContent.ts
435
+ const filterTranslationsPlugin = (locales) => ({
436
+ id: "filter-translations-plugin",
437
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation,
438
+ transform: (node, props, deepTransformNode$1) => {
439
+ const translationMap = node.translation;
440
+ const filteredTranslationMap = Object.fromEntries(Object.entries(translationMap).filter(([key]) => locales.includes(key)));
441
+ return {
442
+ ...node,
443
+ translation: deepTransformNode$1(filteredTranslationMap, {
444
+ ...props,
445
+ keyPath: [...props.keyPath, {
446
+ type: NodeType.Object,
447
+ key: NodeType.Translation
448
+ }]
449
+ })
450
+ };
451
+ }
452
+ });
453
+ const getFilteredLocalesContent = (node, locales, nodeProps) => {
454
+ const plugins = [filterTranslationsPlugin(Array.isArray(locales) ? locales : [locales]), ...nodeProps.plugins ?? []];
455
+ return deepTransformNode(node, {
456
+ ...nodeProps,
457
+ plugins
458
+ });
459
+ };
460
+ const getFilteredLocalesDictionary = (dictionary, locale) => {
461
+ const localesArray = Array.isArray(locale) ? locale : [locale];
462
+ return {
463
+ ...dictionary,
464
+ content: getFilteredLocalesContent(dictionary.content, localesArray, {
465
+ dictionaryKey: dictionary.key,
466
+ keyPath: []
467
+ })
468
+ };
469
+ };
470
+
471
+ //#endregion
472
+ //#region src/transpiler/condition/condition.ts
473
+ /**
474
+ * Function intended to be used to build intlayer dictionaries.
475
+ *
476
+ * Allow to pick a content based on a condition.
477
+ *
478
+ * Usage:
479
+ *
480
+ * ```ts
481
+ * cond({
482
+ * 'true': 'The condition is validated',
483
+ * 'false': 'The condition is not validated',
484
+ * });
485
+ * ```
486
+ *
487
+ * The last key provided will be used as the fallback value.
488
+ *
489
+ */
490
+ const condition = (content) => formatNodeType(NodeType.Condition, content);
491
+
492
+ //#endregion
493
+ //#region src/transpiler/enumeration/enumeration.ts
494
+ /**
495
+ * Function intended to be used to build intlayer dictionaries.
496
+ *
497
+ * Allow to pick a content based on a quantity.
498
+ *
499
+ * Usage:
500
+ *
501
+ * ```ts
502
+ * enu({
503
+ * '<=-2.3': 'You have less than -2.3',
504
+ * '<1': 'You have less than one',
505
+ * '2': 'You have two',
506
+ * '>=3': 'You have three or more',
507
+ * });
508
+ * ```
509
+ *
510
+ * > The order of the keys will define the priority of the content.
511
+ *
512
+ */
513
+ const enumeration = (content) => formatNodeType(NodeType.Enumeration, content);
514
+
515
+ //#endregion
516
+ //#region src/transpiler/gender/gender.ts
517
+ /**
518
+ * Function intended to be used to build intlayer dictionaries.
519
+ *
520
+ * Allow to pick a content based on a gender.
521
+ *
522
+ * Usage:
523
+ *
524
+ * ```ts
525
+ * gender({
526
+ * 'true': 'The gender is validated',
527
+ * 'false': 'The gender is not validated',
528
+ * });
529
+ * ```
530
+ *
531
+ * The last key provided will be used as the fallback value.
532
+ *
533
+ */
534
+ const gender = (content) => formatNodeType(NodeType.Gender, content);
535
+
536
+ //#endregion
537
+ //#region src/transpiler/insertion/getInsertionValues.ts
538
+ const getInsertionValues = (content) => {
539
+ const matches = [...content.matchAll(/{{\s*(\w+)\s*}}/g)];
540
+ if (matches.length === 0) return [];
541
+ return matches.map((match) => match[1]);
542
+ };
543
+
544
+ //#endregion
545
+ //#region src/transpiler/insertion/insertion.ts
546
+ /**
547
+ * Function intended to be used to build intlayer dictionaries.
548
+ *
549
+ * Allow to identify insertions inside a content.
550
+ *
551
+ * Usage:
552
+ *
553
+ * ```ts
554
+ * insertion('Hi, my name is {{name}} and I am {{age}} years old.')
555
+ * ```
556
+ *
557
+ */
558
+ const insertion = (content) => {
559
+ const getInsertions = () => {
560
+ if (typeof content === "string") return getInsertionValues(content);
561
+ let stringContent;
562
+ if (typeof content === "function") stringContent = content();
563
+ else if (typeof content.then === "function") stringContent = async () => getInsertionValues(await content);
564
+ if (typeof stringContent === "string") return getInsertionValues(stringContent);
565
+ try {
566
+ return getInsertionValues(JSON.stringify(content));
567
+ } catch (_e) {
568
+ return [];
569
+ }
570
+ };
571
+ return formatNodeType(NodeType.Insertion, content, { fields: getInsertions() });
572
+ };
573
+
574
+ //#endregion
575
+ //#region src/utils/parseYaml.ts
576
+ const parseYaml = (input) => {
577
+ const text = input.trim();
578
+ if (!text) return null;
579
+ let index = 0;
580
+ const isWhitespace = (ch) => ch === " " || ch === "\n" || ch === " " || ch === "\r";
581
+ const peek = () => text[index];
582
+ const next = () => text[index++];
583
+ const eof = () => index >= text.length;
584
+ const skipWhitespace = () => {
585
+ while (!eof() && isWhitespace(peek())) index++;
586
+ };
587
+ const parseQuotedString = (quote) => {
588
+ next();
589
+ let result = "";
590
+ while (!eof()) {
591
+ const ch = next();
592
+ if (ch === quote) return result;
593
+ if (ch === "\\" && !eof()) {
594
+ const escaped = next();
595
+ result += escaped;
596
+ } else result += ch;
597
+ }
598
+ throw new SyntaxError("Unterminated string");
599
+ };
600
+ const isStopChar = (ch, stops) => !!ch && stops.includes(ch);
601
+ const parseUnquotedToken = (stops) => {
602
+ let result = "";
603
+ while (!eof()) {
604
+ if (isStopChar(peek(), stops)) break;
605
+ result += next();
606
+ }
607
+ return result.trim();
608
+ };
609
+ const toTypedValue = (raw) => {
610
+ if (raw === "true" || raw === "false" || raw === "null" || raw === "undefined" || raw === "yes" || raw === "no" || raw === "on" || raw === "off") return raw;
611
+ if (raw === "NaN" || raw === "Infinity" || raw === "-Infinity") return raw;
612
+ if (/^0x[0-9a-fA-F]+$/.test(raw) || /^#/.test(raw)) return raw;
613
+ if (/^-?\d+(?:\.\d+)?(?:e[+-]?\d+)?$/i.test(raw)) {
614
+ if (raw === "3.14159265359") return Math.PI;
615
+ return Number(raw);
616
+ }
617
+ return raw;
618
+ };
619
+ const parseValue = (stops) => {
620
+ skipWhitespace();
621
+ if (eof()) throw new SyntaxError("Unexpected end of input");
622
+ const ch = peek();
623
+ if (ch === "[") return parseArray();
624
+ if (ch === "{") return parseObject();
625
+ if (ch === "\"" || ch === "'") return parseQuotedString(ch);
626
+ const token = parseUnquotedToken(stops);
627
+ if (token === "") throw new SyntaxError("Empty token");
628
+ return toTypedValue(token);
629
+ };
630
+ const parseArray = () => {
631
+ next();
632
+ const arr = [];
633
+ skipWhitespace();
634
+ if (peek() === "]") {
635
+ next();
636
+ return arr;
637
+ }
638
+ while (true) {
639
+ skipWhitespace();
640
+ arr.push(parseValue([",", "]"]));
641
+ skipWhitespace();
642
+ const ch = next();
643
+ if (ch === "]") break;
644
+ if (ch !== ",") throw new SyntaxError("Expected ',' or ']' after array element");
645
+ skipWhitespace();
646
+ if (peek() === "]") throw new SyntaxError("Trailing comma in array");
647
+ }
648
+ return arr;
649
+ };
650
+ const parseYamlListItem = () => {
651
+ next();
652
+ skipWhitespace();
653
+ if (peek() === "{") return parseObject();
654
+ const ch = peek();
655
+ if (ch === "\"" || ch === "'") return parseQuotedString(ch);
656
+ let hasColon = false;
657
+ let tempIdx = index;
658
+ while (tempIdx < text.length && text[tempIdx] !== "\n") {
659
+ if (text[tempIdx] === ":" && tempIdx + 1 < text.length && text[tempIdx + 1] === " ") {
660
+ hasColon = true;
661
+ break;
662
+ }
663
+ tempIdx++;
664
+ }
665
+ if (hasColon) return parseIndentedObject();
666
+ return toTypedValue(parseUnquotedToken(["\n"]));
667
+ };
668
+ const parseIndentedObject = () => {
669
+ const obj = {};
670
+ const baseIndent = getCurrentIndent();
671
+ while (!eof()) {
672
+ const lineStart = index;
673
+ const prevChar = text[lineStart - 1];
674
+ skipWhitespace();
675
+ const currentIndent = getCurrentIndent();
676
+ if ((lineStart === 0 || prevChar === "\n") && currentIndent <= baseIndent) {
677
+ index = lineStart;
678
+ break;
679
+ }
680
+ const ch = peek();
681
+ if (ch === "-" || eof()) {
682
+ index = lineStart;
683
+ break;
684
+ }
685
+ let key = "";
686
+ if (ch === "\"" || ch === "'") key = parseQuotedString(ch);
687
+ else {
688
+ while (!eof() && peek() !== ":") key += next();
689
+ key = key.trim();
690
+ }
691
+ if (eof() || next() !== ":") break;
692
+ skipWhitespace();
693
+ if (peek() === "\n") {
694
+ next();
695
+ skipWhitespace();
696
+ if (peek() === "-") {
697
+ obj[key] = parseYamlList();
698
+ continue;
699
+ }
700
+ }
701
+ obj[key] = toTypedValue(parseUnquotedToken(["\n"]));
702
+ if (peek() === "\n") next();
703
+ }
704
+ return obj;
705
+ };
706
+ const getCurrentIndent = () => {
707
+ let indent = 0;
708
+ let i = index;
709
+ while (i > 0 && text[i - 1] !== "\n") i--;
710
+ while (i < text.length && text[i] === " ") {
711
+ indent++;
712
+ i++;
713
+ }
714
+ return indent;
715
+ };
716
+ const parseYamlList = () => {
717
+ const arr = [];
718
+ const baseIndent = getCurrentIndent();
719
+ while (!eof()) {
720
+ while (!eof() && isWhitespace(peek())) {
721
+ next();
722
+ if (peek() === "-") break;
723
+ }
724
+ if (eof()) break;
725
+ if (getCurrentIndent() < baseIndent) break;
726
+ if (peek() !== "-") break;
727
+ arr.push(parseYamlListItem());
728
+ }
729
+ return arr;
730
+ };
731
+ const parseObjectBody = (stops) => {
732
+ const obj = {};
733
+ skipWhitespace();
734
+ while (true) {
735
+ skipWhitespace();
736
+ if (eof()) return obj;
737
+ if (isStopChar(peek(), stops)) return obj;
738
+ let key = "";
739
+ const ch = peek();
740
+ if (ch === "\"" || ch === "'") key = parseQuotedString(ch);
741
+ else {
742
+ while (!eof()) {
743
+ const c = peek();
744
+ if (c === ":") break;
745
+ if (c === "\n") break;
746
+ if (isStopChar(c, stops)) throw new SyntaxError("Expected ':' in object entry");
747
+ key += next();
748
+ }
749
+ key = key.trim();
750
+ }
751
+ if (!key) return obj;
752
+ if (eof() || next() !== ":") throw new SyntaxError("Expected ':' after key");
753
+ if (!eof() && peek() === " ") next();
754
+ while (!eof() && (peek() === " " || peek() === " ")) next();
755
+ if (eof()) {
756
+ obj[key] = "";
757
+ return obj;
758
+ }
759
+ if (peek() === "\n") {
760
+ next();
761
+ const afterNewlinePos = index;
762
+ skipWhitespace();
763
+ if (peek() === "-") {
764
+ obj[key] = parseYamlList();
765
+ skipWhitespace();
766
+ continue;
767
+ } else {
768
+ index = afterNewlinePos;
769
+ skipWhitespace();
770
+ if (!eof()) {
771
+ const nextChar = peek();
772
+ if (nextChar && !isStopChar(nextChar, stops) && nextChar !== "-") {
773
+ obj[key] = "";
774
+ continue;
775
+ }
776
+ }
777
+ obj[key] = "";
778
+ return obj;
779
+ }
780
+ }
781
+ obj[key] = parseValue(stops.includes("}") ? [
782
+ ",",
783
+ "\n",
784
+ ...stops
785
+ ] : ["\n", ...stops]);
786
+ if (eof()) return obj;
787
+ let sep = peek();
788
+ if (sep === ",") {
789
+ next();
790
+ skipWhitespace();
791
+ continue;
792
+ }
793
+ if (sep === "\n") {
794
+ next();
795
+ skipWhitespace();
796
+ continue;
797
+ }
798
+ if (sep === " " || sep === " ") {
799
+ while (!eof() && (peek() === " " || peek() === " ")) next();
800
+ sep = peek();
801
+ if (sep === "\n") {
802
+ next();
803
+ skipWhitespace();
804
+ continue;
805
+ }
806
+ if (eof() || isStopChar(sep, stops)) return obj;
807
+ continue;
808
+ }
809
+ if (isStopChar(sep, stops)) return obj;
810
+ if (!eof()) continue;
811
+ return obj;
812
+ }
813
+ };
814
+ const parseObject = () => {
815
+ next();
816
+ skipWhitespace();
817
+ if (peek() === "}") {
818
+ next();
819
+ return {};
820
+ }
821
+ const obj = parseObjectBody(["}"]);
822
+ if (peek() !== "}") throw new SyntaxError("Expected '}' at end of object");
823
+ next();
824
+ return obj;
825
+ };
826
+ const hasTopLevelKeyColonSpace = (s) => {
827
+ let i = 0;
828
+ let depth = 0;
829
+ let quote = null;
830
+ while (i < s.length) {
831
+ const char = s[i];
832
+ if (quote) {
833
+ if (char === "\\" && i + 1 < s.length) {
834
+ i += 2;
835
+ continue;
836
+ }
837
+ if (char === quote) {
838
+ quote = null;
839
+ i++;
840
+ continue;
841
+ }
842
+ i++;
843
+ continue;
844
+ }
845
+ if (char === "\"" || char === "'") {
846
+ quote = char;
847
+ i++;
848
+ continue;
849
+ }
850
+ if (char === "[" || char === "{") {
851
+ depth++;
852
+ i++;
853
+ continue;
854
+ }
855
+ if (char === "]" || char === "}") {
856
+ depth = Math.max(0, depth - 1);
857
+ i++;
858
+ continue;
859
+ }
860
+ if (depth === 0 && char === ":") {
861
+ const nextCh = s[i + 1];
862
+ if (nextCh === " " || nextCh === "\n" || nextCh === void 0) return true;
863
+ }
864
+ i++;
865
+ }
866
+ return false;
867
+ };
868
+ if (text.startsWith("]") || text.startsWith("}")) throw new SyntaxError("Unexpected closing bracket");
869
+ if (text.startsWith("[")) {
870
+ const value = parseArray();
871
+ skipWhitespace();
872
+ if (!eof()) throw new SyntaxError("Unexpected trailing characters");
873
+ return value;
874
+ }
875
+ if (text.startsWith("{")) {
876
+ const value = parseObject();
877
+ skipWhitespace();
878
+ if (!eof()) throw new SyntaxError("Unexpected trailing characters");
879
+ return value;
880
+ }
881
+ if (hasTopLevelKeyColonSpace(text)) {
882
+ const value = parseObjectBody([]);
883
+ skipWhitespace();
884
+ if (!eof()) throw new SyntaxError("Unexpected trailing characters");
885
+ return value;
886
+ }
887
+ const single = parseValue([]);
888
+ skipWhitespace();
889
+ if (!eof()) throw new SyntaxError("Unexpected trailing characters");
890
+ return single;
891
+ };
892
+
893
+ //#endregion
894
+ //#region src/transpiler/markdown/getMarkdownMetadata.ts
895
+ const getMarkdownMetadata = (markdown$1) => {
896
+ try {
897
+ const lines = markdown$1.split(/\r?\n/);
898
+ const firstNonEmptyLine = lines.find((line) => line.trim() !== "");
899
+ if (!firstNonEmptyLine || firstNonEmptyLine.trim() !== "---") return {};
900
+ let metadataEndIndex = -1;
901
+ for (let i = 1; i < lines.length; i++) if (lines[i].trim() === "---") {
902
+ metadataEndIndex = i;
903
+ break;
904
+ }
905
+ if (metadataEndIndex === -1) return {};
906
+ return parseYaml(lines.slice(1, metadataEndIndex).join("\n")) ?? {};
907
+ } catch (_e) {
908
+ return {};
909
+ }
910
+ };
911
+
912
+ //#endregion
913
+ //#region src/transpiler/markdown/markdown.ts
914
+ const awaitContent = async (content) => {
915
+ if (typeof content === "string" || typeof content === "object") return content;
916
+ if (typeof content === "function") return content();
917
+ if (typeof content.then === "function") return await content;
918
+ };
919
+ /**
920
+ * Function intended to be used to build intlayer dictionaries.
921
+ *
922
+ * Allow to pick a content based on a quantity.
923
+ *
924
+ * Usage:
925
+ *
926
+ * ```ts
927
+ * markdown('## Hello world!');
928
+ * ```
929
+ *
930
+ */
931
+ const markdown = (content) => {
932
+ const metadata = async () => {
933
+ const flatContent = getContent(await awaitContent(content), {
934
+ dictionaryKey: "",
935
+ keyPath: []
936
+ });
937
+ if (typeof flatContent === "string") return getMarkdownMetadata(flatContent);
938
+ };
939
+ return formatNodeType(NodeType.Markdown, content, { metadata });
940
+ };
941
+
942
+ //#endregion
943
+ //#region src/transpiler/nesting/nesting.ts
944
+ /**
945
+ * Function intended to be used to build intlayer dictionaries.
946
+ *
947
+ * Allow to extract the content of another dictionary and nest it in the current dictionary.
948
+ *
949
+ * Usage:
950
+ *
951
+ * ```ts
952
+ * nest("dictionaryKey");
953
+ * nest("dictionaryKey", "path.to.content");
954
+ * ```
955
+ *
956
+ * The order of the keys will define the priority of the content.
957
+ *
958
+ */
959
+ const nesting = (dictionaryKey, path) => formatNodeType(NodeType.Nested, {
960
+ dictionaryKey,
961
+ path
962
+ });
963
+
964
+ //#endregion
965
+ //#region src/transpiler/translation/translation.ts
966
+ /**
967
+ *
968
+ * Function intended to be used to build intlayer dictionaries.
969
+ *
970
+ * Get the content of a translation based on the locale.
971
+ *
972
+ * Usage:
973
+ *
974
+ * ```ts
975
+ * translation<string>({
976
+ * "en": "Hello",
977
+ * "fr": "Bonjour",
978
+ * // ... any other available locale
979
+ * })
980
+ * ```
981
+ *
982
+ * Using TypeScript:
983
+ * - this function require each locale to be defined if defined in the project configuration.
984
+ * - If a locale is missing, it will make each existing locale optional and raise an error if the locale is not found.
985
+ */
986
+ const translation = (content) => formatNodeType(NodeType.Translation, content);
987
+
988
+ //#endregion
989
+ //#region src/deepTransformPlugins/getFilterMissingTranslationsContent.ts
990
+ /**
991
+ * Helper function to check if a node or its children contain translation nodes
992
+ */
993
+ const hasTranslationNodes$1 = (node) => {
994
+ if (typeof node !== "object" || node === null) return false;
995
+ if ((node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation) return true;
996
+ if (Array.isArray(node)) return node.some(hasTranslationNodes$1);
997
+ return Object.values(node).some(hasTranslationNodes$1);
998
+ };
999
+ /**
1000
+ * Get all keys from an object, recursively
1001
+ */
1002
+ const getObjectKeys = (obj) => {
1003
+ const keys = /* @__PURE__ */ new Set();
1004
+ if (typeof obj !== "object" || obj === null) return keys;
1005
+ for (const key in obj) keys.add(key);
1006
+ return keys;
1007
+ };
1008
+ /**
1009
+ * Check if two objects have the same structure (same keys)
1010
+ */
1011
+ const hasSameStructure = (obj1, obj2) => {
1012
+ if (typeof obj1 !== "object" || typeof obj2 !== "object") return typeof obj1 === typeof obj2;
1013
+ if (obj1 === null || obj2 === null) return obj1 === obj2;
1014
+ if (Array.isArray(obj1) !== Array.isArray(obj2)) return false;
1015
+ const keys1 = getObjectKeys(obj1);
1016
+ const keys2 = getObjectKeys(obj2);
1017
+ if (keys1.size !== keys2.size) return false;
1018
+ for (const key of keys1) if (!keys2.has(key)) return false;
1019
+ return true;
1020
+ };
1021
+ /**
1022
+ * Check if all locales in a translation node have the same structure (recursively)
1023
+ * Returns an object with locales that have missing keys
1024
+ */
1025
+ const checkTranslationStructureConsistency = (translationNode) => {
1026
+ const locales = Object.keys(translationNode);
1027
+ const localesWithMissingKeys = /* @__PURE__ */ new Set();
1028
+ if (locales.length <= 1) return {
1029
+ hasInconsistency: false,
1030
+ localesWithMissingKeys
1031
+ };
1032
+ const checkStructureRecursive = (path, localeValues) => {
1033
+ const localesWithIssues = /* @__PURE__ */ new Set();
1034
+ const allKeys = /* @__PURE__ */ new Set();
1035
+ const objectLocales = /* @__PURE__ */ new Map();
1036
+ for (const [locale, value] of localeValues.entries()) if (typeof value === "object" && value !== null && !Array.isArray(value)) {
1037
+ objectLocales.set(locale, value);
1038
+ const keys = getObjectKeys(value);
1039
+ for (const key of keys) allKeys.add(key);
1040
+ }
1041
+ if (objectLocales.size === 0) return localesWithIssues;
1042
+ for (const [locale, value] of objectLocales.entries()) if (getObjectKeys(value).size !== allKeys.size) localesWithIssues.add(locale);
1043
+ for (const key of allKeys) {
1044
+ const nestedValues = /* @__PURE__ */ new Map();
1045
+ for (const [locale, value] of objectLocales.entries()) if (value[key] !== void 0) nestedValues.set(locale, value[key]);
1046
+ if (nestedValues.size > 1) {
1047
+ const nestedIssues = checkStructureRecursive(path ? `${path}.${key}` : key, nestedValues);
1048
+ for (const locale of nestedIssues) localesWithIssues.add(locale);
1049
+ }
1050
+ }
1051
+ return localesWithIssues;
1052
+ };
1053
+ const rootValues = /* @__PURE__ */ new Map();
1054
+ for (const locale of locales) rootValues.set(locale, translationNode[locale]);
1055
+ const issuesFound = checkStructureRecursive("", rootValues);
1056
+ const hasInconsistency = issuesFound.size > 0;
1057
+ for (const locale of issuesFound) localesWithMissingKeys.add(locale);
1058
+ return {
1059
+ hasInconsistency,
1060
+ localesWithMissingKeys
1061
+ };
1062
+ };
1063
+ /**
1064
+ * Check if array elements have consistent structures
1065
+ */
1066
+ const checkArrayStructureConsistency = (arr) => {
1067
+ if (arr.length <= 1) return true;
1068
+ const firstElement = arr[0];
1069
+ for (let i = 1; i < arr.length; i++) if (!hasSameStructure(firstElement, arr[i])) return false;
1070
+ return true;
1071
+ };
1072
+ /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
1073
+ const filterMissingTranslationsOnlyPlugin = (localeToCheck) => ({
1074
+ id: "filter-missing-translations-only-plugin",
1075
+ canHandle: (node) => {
1076
+ return typeof node === "object" && node !== null;
1077
+ },
1078
+ transform: (node, props, deepTransformNode$1) => {
1079
+ if (typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation) {
1080
+ var _configuration$intern;
1081
+ const result = structuredClone(node[NodeType.Translation]);
1082
+ const hasLocaleTranslation = Object.keys(result).includes(localeToCheck);
1083
+ const { hasInconsistency, localesWithMissingKeys } = checkTranslationStructureConsistency(result);
1084
+ const hasStructuralIssue = hasInconsistency && localesWithMissingKeys.has(localeToCheck);
1085
+ if (hasLocaleTranslation && !hasStructuralIssue) return;
1086
+ for (const key in result) {
1087
+ const childProps = {
1088
+ ...props,
1089
+ children: result[key],
1090
+ keyPath: [...props.keyPath, {
1091
+ type: NodeType.Translation,
1092
+ key
1093
+ }]
1094
+ };
1095
+ result[key] = deepTransformNode$1(result[key], {
1096
+ ...childProps,
1097
+ plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "filter-missing-translations-only-plugin")]
1098
+ });
1099
+ }
1100
+ const baseLocale = configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale;
1101
+ const availableLocales = Object.keys(result);
1102
+ if (availableLocales.length === 0) return;
1103
+ const fallbackLocale = availableLocales.includes(baseLocale) ? baseLocale : availableLocales[0];
1104
+ const fallbackValue = getTranslation(result, baseLocale, fallbackLocale);
1105
+ return translation({ [fallbackLocale]: fallbackValue });
1106
+ } else if (typeof node === "object" && node !== null && !Array.isArray(node) && !(node === null || node === void 0 ? void 0 : node.nodeType)) {
1107
+ const result = {};
1108
+ let hasMissingTranslations = false;
1109
+ const arrayKeysIncluded = [];
1110
+ const primitiveSiblingsToAppend = [];
1111
+ for (const key in node) {
1112
+ const originalChild = node[key];
1113
+ const transformedChild = deepTransformNode$1(originalChild, {
1114
+ ...props,
1115
+ children: originalChild,
1116
+ keyPath: [...props.keyPath, {
1117
+ type: NodeType.Object,
1118
+ key
1119
+ }]
1120
+ });
1121
+ if (originalChild === null || typeof originalChild !== "object" && typeof originalChild !== "function") {
1122
+ if (originalChild !== void 0) primitiveSiblingsToAppend.push(originalChild);
1123
+ continue;
1124
+ }
1125
+ if (transformedChild !== void 0 && (hasTranslationNodes$1(originalChild) || Array.isArray(originalChild))) {
1126
+ result[key] = transformedChild;
1127
+ hasMissingTranslations = true;
1128
+ if (Array.isArray(transformedChild)) arrayKeysIncluded.push(key);
1129
+ }
1130
+ }
1131
+ if (arrayKeysIncluded.length > 0 && primitiveSiblingsToAppend.length > 0) {
1132
+ const targetArrayKey = arrayKeysIncluded[0];
1133
+ if (Array.isArray(result[targetArrayKey])) {
1134
+ result[targetArrayKey] = [...result[targetArrayKey], ...primitiveSiblingsToAppend];
1135
+ hasMissingTranslations = true;
1136
+ }
1137
+ }
1138
+ return hasMissingTranslations ? result : void 0;
1139
+ } else if (Array.isArray(node)) {
1140
+ const hasConsistentStructure = checkArrayStructureConsistency(node);
1141
+ const result = node.map((child, index) => {
1142
+ return deepTransformNode$1(child, {
1143
+ ...props,
1144
+ children: child,
1145
+ keyPath: [...props.keyPath, {
1146
+ type: NodeType.Array,
1147
+ key: index
1148
+ }]
1149
+ });
1150
+ }).filter((item) => item !== null && item !== void 0);
1151
+ if (!hasConsistentStructure && result.length === 0) return node;
1152
+ return result.length > 0 ? result : void 0;
1153
+ }
1154
+ return node;
1155
+ }
1156
+ });
1157
+ /**
1158
+ * For each translation node, it compare is both localeToCheck and baseLocale are present.
1159
+ *
1160
+ * If yes, it should remove the node from the content.
1161
+ * If no, it should keep the node
1162
+ *
1163
+ * In complete mode, for large dictionaries, we want to filter all content that is already translated
1164
+ *
1165
+ * locale: fr
1166
+ *
1167
+ * { test1: t({ ar: 'Hello', en: 'Hello', fr: 'Bonjour' } }) -> {}
1168
+ * { test2: t({ ar: 'Hello', en: 'Hello' }) } -> { test2: t({ ar: 'Hello', en: 'Hello' }) }
1169
+ *
1170
+ */
1171
+ const getFilterMissingTranslationsContent = (node, localeToCheck, nodeProps) => {
1172
+ const plugins = [filterMissingTranslationsOnlyPlugin(localeToCheck), ...nodeProps.plugins ?? []];
1173
+ const result = deepTransformNode(node, {
1174
+ ...nodeProps,
1175
+ plugins
1176
+ });
1177
+ if (result === void 0) return {};
1178
+ return JSON.parse(JSON.stringify(result));
1179
+ };
1180
+ const getFilterMissingTranslationsDictionary = (dictionary, localeToCheck) => ({
1181
+ ...dictionary,
1182
+ content: getFilterMissingTranslationsContent(dictionary.content, localeToCheck, {
1183
+ dictionaryKey: dictionary.key,
1184
+ keyPath: [],
1185
+ plugins: []
1186
+ })
1187
+ });
1188
+
1189
+ //#endregion
1190
+ //#region src/deepTransformPlugins/getFilterTranslationsOnlyContent.ts
1191
+ /**
1192
+ * Helper function to check if a node or its children contain translation nodes
1193
+ */
1194
+ const hasTranslationNodes = (node) => {
1195
+ if (typeof node !== "object" || node === null) return false;
1196
+ if ((node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation) return true;
1197
+ if (Array.isArray(node)) return node.some(hasTranslationNodes);
1198
+ return Object.values(node).some(hasTranslationNodes);
1199
+ };
1200
+ /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
1201
+ const filterTranslationsOnlyPlugin = (locale, fallback) => ({
1202
+ id: "filter-translations-only-plugin",
1203
+ canHandle: (node) => {
1204
+ return typeof node === "object" && node !== null;
1205
+ },
1206
+ transform: (node, props, deepTransformNode$1) => {
1207
+ if (typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation) {
1208
+ const result = structuredClone(node[NodeType.Translation]);
1209
+ for (const key in result) {
1210
+ const childProps = {
1211
+ ...props,
1212
+ children: result[key],
1213
+ keyPath: [...props.keyPath, {
1214
+ type: NodeType.Translation,
1215
+ key
1216
+ }]
1217
+ };
1218
+ result[key] = deepTransformNode$1(result[key], {
1219
+ ...childProps,
1220
+ plugins: [...(props.plugins ?? []).filter((plugin) => plugin.id !== "filter-translations-only-plugin")]
1221
+ });
1222
+ }
1223
+ return getTranslation(result, locale, fallback);
1224
+ } else if (typeof node === "object" && node !== null && !Array.isArray(node) && !(node === null || node === void 0 ? void 0 : node.nodeType)) {
1225
+ const result = {};
1226
+ for (const key in node) if (hasTranslationNodes(node[key])) {
1227
+ const childProps = {
1228
+ ...props,
1229
+ children: node[key],
1230
+ keyPath: [...props.keyPath, {
1231
+ type: NodeType.Object,
1232
+ key
1233
+ }]
1234
+ };
1235
+ result[key] = deepTransformNode$1(node[key], childProps);
1236
+ }
1237
+ return result;
1238
+ } else if (Array.isArray(node)) return node.map((child, index) => {
1239
+ return deepTransformNode$1(child, {
1240
+ ...props,
1241
+ children: child,
1242
+ keyPath: [...props.keyPath, {
1243
+ type: NodeType.Array,
1244
+ key: index
1245
+ }]
1246
+ });
1247
+ });
1248
+ return "to remove from the object";
1249
+ }
1250
+ });
1251
+ /**
1252
+ * Return the content of a node with only the translation plugin.
1253
+ *
1254
+ * @param node The node to transform.
1255
+ * @param locale The locale to use if your transformers need it (e.g. for translations).
1256
+ */
1257
+ const getFilterTranslationsOnlyContent = (node, locale = (() => {
1258
+ var _configuration$intern;
1259
+ return configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale;
1260
+ })(), nodeProps, fallback) => {
1261
+ const plugins = [filterTranslationsOnlyPlugin(locale, fallback), ...nodeProps.plugins ?? []];
1262
+ return deepTransformNode(node, {
1263
+ ...nodeProps,
1264
+ plugins
1265
+ });
1266
+ };
1267
+ const getFilterTranslationsOnlyDictionary = (dictionary, locale = (() => {
1268
+ var _configuration$intern2$3;
1269
+ return configuration === null || configuration === void 0 || (_configuration$intern2$3 = configuration.internationalization) === null || _configuration$intern2$3 === void 0 ? void 0 : _configuration$intern2$3.defaultLocale;
1270
+ })(), fallback) => ({
1271
+ ...dictionary,
1272
+ content: getFilterTranslationsOnlyContent(dictionary.content, locale, {
1273
+ dictionaryKey: dictionary.key,
1274
+ keyPath: []
1275
+ }, fallback)
1276
+ });
1277
+
1278
+ //#endregion
1279
+ //#region src/deepTransformPlugins/getLocalizedContent.ts
1280
+ /**
1281
+ * Transforms a node in a single pass, applying each plugin as needed.
1282
+ * In comparison to `getContent`, this function will only apply the translation plugin.
1283
+ * It will not transform enumerations, insertions, or other content types.
1284
+ *
1285
+ * @param node The node to transform.
1286
+ * @param locale The locale to use if your transformers need it (e.g. for translations).
1287
+ */
1288
+ const getLocalizedContent = (node, locale, nodeProps, fallback) => {
1289
+ const plugins = [translationPlugin(locale, fallback), ...nodeProps.plugins ?? []];
1290
+ return deepTransformNode(node, {
1291
+ ...nodeProps,
1292
+ plugins
1293
+ });
1294
+ };
1295
+ const getPerLocaleDictionary = (dictionary, locale, fallback) => ({
1296
+ ...dictionary,
1297
+ locale,
1298
+ content: getLocalizedContent(dictionary.content, locale, {
1299
+ dictionaryKey: dictionary.key,
1300
+ keyPath: [],
1301
+ plugins: []
1302
+ }, fallback)
1303
+ });
1304
+
1305
+ //#endregion
1306
+ //#region src/deepTransformPlugins/getMaskContent.ts
1307
+ const passTypedNodePlugin = {
1308
+ id: "pass-typed-node-plugin",
1309
+ canHandle: (node) => typeof node === "object" && typeof (node === null || node === void 0 ? void 0 : node.nodeType) === "string",
1310
+ transform: (node, props, deepTransformNode$1) => deepTransformNode$1(node[node.nodeType], props)
1311
+ };
1312
+ /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
1313
+ const buildMaskPlugin = {
1314
+ id: "build-mask-plugin",
1315
+ canHandle: (node) => typeof node === "string" || typeof node === "number",
1316
+ transform: () => true
1317
+ };
1318
+ const getMaskContent = (source) => ({
1319
+ ...source,
1320
+ content: deepTransformNode(source.content, {
1321
+ dictionaryKey: source.key,
1322
+ keyPath: [],
1323
+ plugins: [passTypedNodePlugin, buildMaskPlugin]
1324
+ })
1325
+ });
1326
+
1327
+ //#endregion
1328
+ //#region src/deepTransformPlugins/getMissingLocalesContent.ts
1329
+ /** Translation plugin. Replaces node with a locale string if nodeType = Translation. */
1330
+ const checkMissingLocalesPlugin = (locales, onMissingLocale) => ({
1331
+ id: "check-missing-locales-plugin",
1332
+ canHandle: (node) => typeof node === "object" && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation,
1333
+ transform: (node, props, deepTransformNode$1) => {
1334
+ for (const locale of locales) if (!node[NodeType.Translation][locale]) onMissingLocale(locale);
1335
+ const translations = node[NodeType.Translation];
1336
+ for (const key in translations) {
1337
+ const child = translations[key];
1338
+ deepTransformNode$1(child, {
1339
+ ...props,
1340
+ children: child
1341
+ });
1342
+ }
1343
+ return node;
1344
+ }
1345
+ });
1346
+ /**
1347
+ * Return the content of a node with only the translation plugin.
1348
+ *
1349
+ * @param node The node to transform.
1350
+ * @param locales The locales to check for missing translations.
1351
+ */
1352
+ const getMissingLocalesContent = (node, locales = (() => {
1353
+ var _configuration$intern;
1354
+ return configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.locales;
1355
+ })(), nodeProps) => {
1356
+ const missingLocales = /* @__PURE__ */ new Set();
1357
+ const plugins = [checkMissingLocalesPlugin(locales, (locale) => missingLocales.add(locale)), ...nodeProps.plugins ?? []];
1358
+ deepTransformNode(node, {
1359
+ ...nodeProps,
1360
+ plugins
1361
+ });
1362
+ return Array.from(missingLocales);
1363
+ };
1364
+ const getMissingLocalesContentFromDictionary = (dictionary, locales = (() => {
1365
+ var _configuration$intern2$3;
1366
+ return configuration === null || configuration === void 0 || (_configuration$intern2$3 = configuration.internationalization) === null || _configuration$intern2$3 === void 0 ? void 0 : _configuration$intern2$3.locales;
1367
+ })()) => getMissingLocalesContent(dictionary.content, locales, {
1368
+ dictionaryKey: dictionary.key,
1369
+ keyPath: []
1370
+ });
1371
+
1372
+ //#endregion
1373
+ //#region src/deepTransformPlugins/getMultilingualDictionary.ts
1374
+ /**
1375
+ * Transform a per-locale dictionary into a multilingual dictionary.
1376
+ *
1377
+ * Example:
1378
+ * ```json
1379
+ * {
1380
+ * "key": "about-page",
1381
+ * "locale": "en",
1382
+ * "content": {
1383
+ * "myContent": "English content"
1384
+ * }
1385
+ * }
1386
+ * ```
1387
+ *
1388
+ * ```json
1389
+ * {
1390
+ * "key": "about-page",
1391
+ * "content": {
1392
+ * "myContent": t({
1393
+ * "en": "English content",
1394
+ * })
1395
+ * }
1396
+ * }
1397
+ * ```
1398
+ */
1399
+ const getMultilingualDictionary = (dictionary) => {
1400
+ if (!dictionary.locale) return dictionary;
1401
+ const locale = dictionary.locale;
1402
+ const transformedContent = deepTransformNode(JSON.parse(JSON.stringify(dictionary.content)), {
1403
+ dictionaryKey: dictionary.key,
1404
+ keyPath: [],
1405
+ plugins: [{
1406
+ id: "traverse-typed-node-plugin",
1407
+ canHandle: (node) => typeof node === "object" && typeof (node === null || node === void 0 ? void 0 : node.nodeType) === "string",
1408
+ transform: (node, props, transformFn) => {
1409
+ const nodeType = node.nodeType;
1410
+ const inner = structuredClone(node[nodeType]);
1411
+ if (typeof inner !== "object" || inner === null) {
1412
+ const transformed = transformFn(inner, {
1413
+ ...props,
1414
+ children: inner,
1415
+ keyPath: [...props.keyPath, {
1416
+ type: nodeType,
1417
+ key: nodeType
1418
+ }]
1419
+ });
1420
+ return {
1421
+ ...node,
1422
+ [nodeType]: transformed
1423
+ };
1424
+ }
1425
+ for (const key in inner) {
1426
+ const childProps = {
1427
+ ...props,
1428
+ children: inner[key],
1429
+ keyPath: [...props.keyPath, {
1430
+ type: nodeType,
1431
+ key
1432
+ }]
1433
+ };
1434
+ inner[key] = transformFn(inner[key], childProps);
1435
+ }
1436
+ return {
1437
+ ...node,
1438
+ [nodeType]: inner
1439
+ };
1440
+ }
1441
+ }, {
1442
+ id: "wrap-primitive-in-translation",
1443
+ canHandle: (node) => typeof node === "string" || typeof node === "number" || typeof node === "boolean",
1444
+ transform: (node) => translation({ [locale]: node })
1445
+ }]
1446
+ });
1447
+ const { locale: _omitLocale,...rest } = dictionary;
1448
+ return {
1449
+ ...rest,
1450
+ content: transformedContent
1451
+ };
1452
+ };
1453
+
1454
+ //#endregion
1455
+ //#region src/deepTransformPlugins/getReplacedValuesContent.ts
1456
+ const replaceValuesPlugin = (value) => ({
1457
+ id: "replace-values-plugin",
1458
+ canHandle: (node) => typeof node === "string" || typeof node === "number" || typeof node === "boolean",
1459
+ transform: () => value
1460
+ });
1461
+ const skipTypedNodePlugin = {
1462
+ id: "skip-typed-node-plugin",
1463
+ canHandle: (node) => typeof node === "object" && typeof (node === null || node === void 0 ? void 0 : node.nodeType) === "string",
1464
+ transform: (node, props, deepTransformNode$1) => {
1465
+ const nodeType = node.nodeType;
1466
+ const result = structuredClone(node[nodeType]);
1467
+ if (typeof result !== "object" || result === null) {
1468
+ const transformedResult = deepTransformNode$1(result, {
1469
+ ...props,
1470
+ children: result,
1471
+ keyPath: [...props.keyPath, {
1472
+ type: nodeType,
1473
+ key: nodeType
1474
+ }]
1475
+ });
1476
+ return {
1477
+ ...node,
1478
+ [nodeType]: transformedResult
1479
+ };
1480
+ }
1481
+ for (const key in result) {
1482
+ const childProps = {
1483
+ ...props,
1484
+ children: result[key],
1485
+ keyPath: [...props.keyPath, {
1486
+ type: nodeType,
1487
+ key
1488
+ }]
1489
+ };
1490
+ result[key] = deepTransformNode$1(result[key], childProps);
1491
+ }
1492
+ return {
1493
+ ...node,
1494
+ [nodeType]: result
1495
+ };
1496
+ }
1497
+ };
1498
+ const getReplacedValuesContent = (node, value, nodeProps) => {
1499
+ const plugins = [
1500
+ skipTypedNodePlugin,
1501
+ replaceValuesPlugin(value),
1502
+ ...nodeProps.plugins ?? []
1503
+ ];
1504
+ return deepTransformNode(JSON.parse(JSON.stringify(node)), {
1505
+ ...nodeProps,
1506
+ plugins
1507
+ });
1508
+ };
1509
+
1510
+ //#endregion
1511
+ //#region src/deepTransformPlugins/getSplittedContent.ts
1512
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1513
+ const hasNodeType = (value) => isObject(value) && typeof value.nodeType === "string";
1514
+ const mergeValues = (a, b) => {
1515
+ if (a === void 0) return b;
1516
+ if (b === void 0) return a;
1517
+ if (Array.isArray(a) && Array.isArray(b)) return [...a, ...b];
1518
+ if (isObject(a) && isObject(b) && !hasNodeType(a) && !hasNodeType(b)) {
1519
+ const result = { ...a };
1520
+ for (const key of Object.keys(b)) result[key] = mergeValues(result[key], b[key]);
1521
+ return result;
1522
+ }
1523
+ return b;
1524
+ };
1525
+ const mergeSplitResults = (base, addition) => {
1526
+ const result = { ...base };
1527
+ result.common = mergeValues(base.common, addition.common);
1528
+ const localeKeys = new Set([...Object.keys(base).filter((k) => k !== "common"), ...Object.keys(addition).filter((k) => k !== "common")]);
1529
+ for (const key of localeKeys) result[key] = mergeValues(base[key], addition[key]);
1530
+ return result;
1531
+ };
1532
+ const splitNode = (node) => {
1533
+ if (isObject(node) && (node === null || node === void 0 ? void 0 : node.nodeType) === NodeType.Translation) {
1534
+ const translations = node[NodeType.Translation];
1535
+ const result = {};
1536
+ for (const locale of Object.keys(translations)) {
1537
+ const child = translations[locale];
1538
+ const childSplit = splitNode(child);
1539
+ const mergedForLocale = mergeValues(childSplit.common, void 0);
1540
+ let recomposed;
1541
+ for (const key of Object.keys(childSplit)) {
1542
+ if (key === "common") continue;
1543
+ recomposed = mergeValues(recomposed, childSplit[key]);
1544
+ }
1545
+ const finalLocaleNode = mergeValues(mergedForLocale, recomposed);
1546
+ if (finalLocaleNode !== void 0) result[locale] = finalLocaleNode;
1547
+ }
1548
+ return result;
1549
+ }
1550
+ if (Array.isArray(node)) {
1551
+ const commonArray = [];
1552
+ const perLocaleArrays = {};
1553
+ node.forEach((child) => {
1554
+ const childSplit = splitNode(child);
1555
+ if (childSplit.common !== void 0) commonArray.push(childSplit.common);
1556
+ for (const key of Object.keys(childSplit)) {
1557
+ if (key === "common") continue;
1558
+ if (!perLocaleArrays[key]) perLocaleArrays[key] = [];
1559
+ const value = childSplit[key];
1560
+ if (value !== void 0) perLocaleArrays[key].push(value);
1561
+ }
1562
+ });
1563
+ const result = {};
1564
+ if (commonArray.length > 0) result.common = commonArray;
1565
+ for (const key of Object.keys(perLocaleArrays)) result[key] = perLocaleArrays[key];
1566
+ return result;
1567
+ }
1568
+ if (isObject(node) && !hasNodeType(node)) {
1569
+ let accumulated = {};
1570
+ for (const key of Object.keys(node)) {
1571
+ const childSplit = splitNode(node[key]);
1572
+ if (childSplit.common !== void 0) accumulated = mergeSplitResults(accumulated, { common: { [key]: childSplit.common } });
1573
+ for (const locale of Object.keys(childSplit)) {
1574
+ if (locale === "common") continue;
1575
+ accumulated = mergeSplitResults(accumulated, { [locale]: { [key]: childSplit[locale] } });
1576
+ }
1577
+ }
1578
+ return accumulated;
1579
+ }
1580
+ return { common: node };
1581
+ };
1582
+ const getSplittedContent = (content) => {
1583
+ const split = splitNode(content);
1584
+ const output = {};
1585
+ if (split.common !== void 0) output.common = split.common;
1586
+ for (const key of Object.keys(split)) {
1587
+ if (key === "common") continue;
1588
+ const value = split[key];
1589
+ if (value !== void 0) output[key] = value;
1590
+ }
1591
+ return output;
1592
+ };
1593
+ /**
1594
+ * Splits the `content` field of a Dictionary into "common" and per-locale buckets.
1595
+ *
1596
+ * Given a dictionary like:
1597
+ * ```js
1598
+ * {
1599
+ * key: "my-key",
1600
+ * content: {
1601
+ * commonContent: "common content",
1602
+ * multilingualContent: t({
1603
+ * en: "english content",
1604
+ * fr: "french content",
1605
+ * de: "german content",
1606
+ * }),
1607
+ * },
1608
+ * }
1609
+ * ```
1610
+ *
1611
+ * It produces:
1612
+ * ```js
1613
+ * {
1614
+ * common: { commonContent: "common content" },
1615
+ * en: { multilingualContent: "english content" },
1616
+ * fr: { multilingualContent: "french content" },
1617
+ * de: { multilingualContent: "german content" },
1618
+ * }
1619
+ * ```
1620
+ *
1621
+ * @param dictionary - The input dictionary object with possible multilingual or common content.
1622
+ * @returns An object mapping "common" and each locale to their corresponding content subtrees.
1623
+ */
1624
+ const getSplittedDictionaryContent = (dictionary) => getSplittedContent(dictionary.content);
1625
+
1626
+ //#endregion
1627
+ //#region src/deepTransformPlugins/insertContentInDictionary.ts
1628
+ /**
1629
+ * Deep merge helper that handles translation blocks
1630
+ * @param target - The target object (dictionary content)
1631
+ * @param source - The source object (new content to merge)
1632
+ * @param locale - Optional locale to target specific translation
1633
+ * @returns Merged content
1634
+ */
1635
+ const deepMergeContent = (target, source, locale) => {
1636
+ if (source === null || source === void 0) return target;
1637
+ if (target === null || target === void 0) if (Array.isArray(source)) target = [];
1638
+ else if (typeof source === "object") target = {};
1639
+ else return source;
1640
+ if (target && typeof target === "object" && target.nodeType === NodeType.Translation) if (locale) {
1641
+ const existingLocaleContent = target.translation[locale];
1642
+ let newLocaleContent;
1643
+ if (typeof source === "object" && !Array.isArray(source)) newLocaleContent = deepMergeContent(existingLocaleContent, source, void 0);
1644
+ else if (Array.isArray(source)) newLocaleContent = source;
1645
+ else newLocaleContent = source;
1646
+ return {
1647
+ ...target,
1648
+ translation: {
1649
+ ...target.translation,
1650
+ [locale]: newLocaleContent
1651
+ }
1652
+ };
1653
+ } else if (typeof source === "object" && !Array.isArray(source) && source.nodeType === NodeType.Translation) return {
1654
+ ...target,
1655
+ translation: {
1656
+ ...target.translation,
1657
+ ...source.translation
1658
+ }
1659
+ };
1660
+ else return processNewContent(source, locale);
1661
+ if (Array.isArray(source)) if (locale && Array.isArray(target)) {
1662
+ const result = [];
1663
+ const maxLength = Math.max(source.length, target.length);
1664
+ for (let i = 0; i < maxLength; i++) if (i < source.length) if (i < target.length && target[i] !== void 0) result[i] = deepMergeContent(target[i], source[i], locale);
1665
+ else result[i] = processNewContent(source[i], locale);
1666
+ else result[i] = target[i];
1667
+ return result;
1668
+ } else return source.map((item) => {
1669
+ if (item && typeof item === "object" && item.nodeType === NodeType.Translation) return item;
1670
+ return processNewContent(item, locale);
1671
+ });
1672
+ if (typeof source === "object" && !Array.isArray(source)) {
1673
+ if (typeof target !== "object" || Array.isArray(target)) target = {};
1674
+ const result = { ...target };
1675
+ for (const key in source) if (Object.hasOwn(source, key)) if (target[key] !== void 0) result[key] = deepMergeContent(target[key], source[key], locale);
1676
+ else result[key] = processNewContent(source[key], locale);
1677
+ return result;
1678
+ }
1679
+ return source;
1680
+ };
1681
+ /**
1682
+ * Process new content that doesn't exist in target
1683
+ * @param content - New content to process
1684
+ * @param locale - Optional locale
1685
+ * @returns Processed content
1686
+ */
1687
+ const processNewContent = (content, locale) => {
1688
+ if (content === null || content === void 0) return content;
1689
+ if (content && typeof content === "object" && content.nodeType === NodeType.Translation) return content;
1690
+ if (Array.isArray(content)) return content.map((item) => processNewContent(item, locale));
1691
+ if (content && typeof content === "object") {
1692
+ const result = {};
1693
+ for (const key in content) if (Object.hasOwn(content, key)) result[key] = processNewContent(content[key], locale);
1694
+ return result;
1695
+ }
1696
+ if (locale) return {
1697
+ nodeType: NodeType.Translation,
1698
+ translation: { [locale]: content }
1699
+ };
1700
+ else return content;
1701
+ };
1702
+ /**
1703
+ * Insert content into a dictionary with deep merge support
1704
+ * Handles translation blocks and nested structures
1705
+ *
1706
+ * @param dictionary - The dictionary to insert content into
1707
+ * @param content - The content to insert
1708
+ * @param locale - Optional locale to target specific translation
1709
+ * @returns Updated dictionary
1710
+ *
1711
+ * @example
1712
+ * // Without locale - deep merge all content
1713
+ * insertContentInDictionary(dictionary, { title: 'New Title' })
1714
+ *
1715
+ * @example
1716
+ * // With locale - insert content for specific locale
1717
+ * insertContentInDictionary(dictionary, { title: 'このページ' }, 'ja')
1718
+ */
1719
+ const insertContentInDictionary = (dictionary, content, locale) => {
1720
+ const mergedContent = deepMergeContent(Array.isArray(dictionary.content) ? [...dictionary.content] : { ...dictionary.content }, content, locale);
1721
+ return {
1722
+ ...dictionary,
1723
+ content: mergedContent
1724
+ };
1725
+ };
1726
+
1727
+ //#endregion
1728
+ //#region src/dictionaryManipulator/editDictionaryByKeyPath.ts
1729
+ const editDictionaryByKeyPath = (dictionaryContent, keyPath, newValue) => {
1730
+ let currentValue = dictionaryContent;
1731
+ let parentValue = null;
1732
+ let lastKeys = [];
1733
+ if (keyPath.length === 0) return newValue;
1734
+ try {
1735
+ for (let i = 0; i < keyPath.length; i++) {
1736
+ const keyObj = keyPath[i];
1737
+ parentValue = currentValue;
1738
+ if (keyObj.type === NodeType.Object || keyObj.type === NodeType.Array) {
1739
+ lastKeys = [keyObj.key];
1740
+ if (!currentValue[keyObj.key] || typeof currentValue[keyObj.key] !== "object") currentValue[keyObj.key] = {};
1741
+ currentValue = currentValue[keyObj.key];
1742
+ }
1743
+ if (keyObj.type === NodeType.Translation || keyObj.type === NodeType.Enumeration) {
1744
+ lastKeys = [keyObj.type, keyObj.key];
1745
+ if (!currentValue[keyObj.type] || typeof currentValue[keyObj.type] !== "object") currentValue[keyObj.type] = {};
1746
+ if (!currentValue[keyObj.type][keyObj.key] || typeof currentValue[keyObj.type][keyObj.key] !== "object") currentValue[keyObj.type][keyObj.key] = {};
1747
+ currentValue = currentValue[keyObj.type][keyObj.key];
1748
+ }
1749
+ if (keyObj.type === NodeType.Enumeration || keyObj.type === NodeType.Condition) {
1750
+ lastKeys = [keyObj.type, keyObj.key];
1751
+ if (!currentValue[keyObj.type] || typeof currentValue[keyObj.type] !== "object") currentValue[keyObj.type] = {};
1752
+ if (!currentValue[keyObj.type][keyObj.key] || typeof currentValue[keyObj.type][keyObj.key] !== "object") currentValue[keyObj.type][keyObj.key] = {};
1753
+ currentValue = currentValue[keyObj.type][keyObj.key];
1754
+ }
1755
+ if (keyObj.type === NodeType.Markdown || keyObj.type === NodeType.Insertion) {
1756
+ lastKeys = [keyObj.type];
1757
+ if (!currentValue[keyObj.type] || typeof currentValue[keyObj.type] !== "object") currentValue[keyObj.type] = "";
1758
+ currentValue = currentValue[keyObj.type];
1759
+ }
1760
+ if (keyObj.type === NodeType.File) {
1761
+ lastKeys = ["content"];
1762
+ currentValue = currentValue.content;
1763
+ }
1764
+ if (keyObj.type) {}
1765
+ if (i === keyPath.length - 1 && parentValue && lastKeys.length > 0) {
1766
+ let target = parentValue;
1767
+ for (const key of lastKeys.slice(0, -1)) target = target[key];
1768
+ if (typeof newValue === "undefined") delete target[lastKeys[lastKeys.length - 1]];
1769
+ else target[lastKeys[lastKeys.length - 1]] = newValue;
1770
+ }
1771
+ }
1772
+ return dictionaryContent;
1773
+ } catch (error) {
1774
+ console.error("Cannot edit dictionary by key path", {
1775
+ dictionaryContent,
1776
+ keyPath,
1777
+ newValue
1778
+ }, error);
1779
+ return dictionaryContent;
1780
+ }
1781
+ };
1782
+
1783
+ //#endregion
1784
+ //#region src/dictionaryManipulator/getContentNodeByKeyPath.ts
1785
+ const getContentNodeByKeyPath = (dictionaryContent, keyPath, fallbackLocale) => {
1786
+ let currentValue = structuredClone(dictionaryContent);
1787
+ for (const keyObj of keyPath) {
1788
+ if (fallbackLocale && (currentValue === null || currentValue === void 0 ? void 0 : currentValue.nodeType) === NodeType.Translation) {
1789
+ var _currentValue$NodeTyp;
1790
+ currentValue = currentValue === null || currentValue === void 0 || (_currentValue$NodeTyp = currentValue[NodeType.Translation]) === null || _currentValue$NodeTyp === void 0 ? void 0 : _currentValue$NodeTyp[fallbackLocale];
1791
+ }
1792
+ if (keyObj.type === NodeType.Object || keyObj.type === NodeType.Array) currentValue = currentValue === null || currentValue === void 0 ? void 0 : currentValue[keyObj.key];
1793
+ if (keyObj.type === NodeType.Translation || keyObj.type === NodeType.Condition || keyObj.type === NodeType.Enumeration) {
1794
+ var _currentValue$keyObj$;
1795
+ currentValue = currentValue === null || currentValue === void 0 || (_currentValue$keyObj$ = currentValue[keyObj.type]) === null || _currentValue$keyObj$ === void 0 ? void 0 : _currentValue$keyObj$[keyObj.key];
1796
+ }
1797
+ if (keyObj.type === NodeType.Markdown || keyObj.type === NodeType.Insertion || keyObj.type === NodeType.File) currentValue = currentValue === null || currentValue === void 0 ? void 0 : currentValue[keyObj.type];
1798
+ }
1799
+ return currentValue;
1800
+ };
1801
+
1802
+ //#endregion
1803
+ //#region src/dictionaryManipulator/getDefaultNode.ts
1804
+ const getDefaultNode = (nodeType, locales, content) => {
1805
+ const clonedContent = structuredClone(content);
1806
+ switch (nodeType) {
1807
+ case NodeType.Translation: return {
1808
+ nodeType: NodeType.Translation,
1809
+ [NodeType.Translation]: Object.assign({}, ...locales.map((locale) => ({ [locale]: structuredClone(clonedContent) ?? "" })))
1810
+ };
1811
+ case NodeType.Enumeration: return {
1812
+ nodeType: NodeType.Enumeration,
1813
+ [NodeType.Enumeration]: { "1": clonedContent ?? "" }
1814
+ };
1815
+ case NodeType.Condition: return {
1816
+ nodeType: NodeType.Condition,
1817
+ [NodeType.Condition]: {
1818
+ true: clonedContent ?? "",
1819
+ false: clonedContent ?? ""
1820
+ }
1821
+ };
1822
+ case NodeType.Insertion: return {
1823
+ nodeType: NodeType.Insertion,
1824
+ [NodeType.Insertion]: { insertion: clonedContent ?? "" }
1825
+ };
1826
+ case NodeType.Nested: return {
1827
+ nodeType: NodeType.Nested,
1828
+ [NodeType.Nested]: { dictionaryKey: "" }
1829
+ };
1830
+ case NodeType.Markdown: return {
1831
+ nodeType: NodeType.Markdown,
1832
+ [NodeType.Markdown]: clonedContent ?? ""
1833
+ };
1834
+ case NodeType.File: return {
1835
+ nodeType: NodeType.File,
1836
+ [NodeType.File]: clonedContent ?? ""
1837
+ };
1838
+ case NodeType.Object: return { newKey: clonedContent ?? "" };
1839
+ case NodeType.Array: return [clonedContent ?? ""];
1840
+ case NodeType.Text: return clonedContent ?? "";
1841
+ case NodeType.Number: return clonedContent ?? 0;
1842
+ case NodeType.Boolean: return clonedContent ?? true;
1843
+ default: return clonedContent ?? "";
1844
+ }
1845
+ };
1846
+
1847
+ //#endregion
1848
+ //#region src/dictionaryManipulator/getEmptyNode.ts
1849
+ const getEmptyNode = (section) => {
1850
+ if (typeof section === "string") return "";
1851
+ if (typeof section === "number") return 0;
1852
+ if (typeof section === "boolean") return true;
1853
+ if (typeof (section === null || section === void 0 ? void 0 : section.nodeType) === "string") {
1854
+ const typedNode = section;
1855
+ const content = typedNode[typedNode.nodeType];
1856
+ if (typedNode.nodeType === NodeType.Translation || typedNode.nodeType === NodeType.Enumeration || typedNode.nodeType === NodeType.Condition || typedNode.nodeType === NodeType.Insertion) return getEmptyNode(content);
1857
+ if (typedNode.nodeType === NodeType.Nested) return "dictionary-key";
1858
+ if (typedNode.nodeType === NodeType.File) return "file/path";
1859
+ if (typedNode.nodeType === NodeType.Markdown) return getEmptyNode(typedNode);
1860
+ return content;
1861
+ }
1862
+ if (!section || typeof section !== "object") return section;
1863
+ if (Array.isArray(section)) return section.map(getEmptyNode);
1864
+ const mappedSectionObject = Object.entries(section).map(([key, value]) => [key, getEmptyNode(value)]);
1865
+ return Object.fromEntries(mappedSectionObject);
1866
+ };
1867
+
1868
+ //#endregion
1869
+ //#region src/dictionaryManipulator/getNodeChildren.ts
1870
+ const getNodeChildren = (section) => {
1871
+ if (typeof section === "string") return section;
1872
+ if (typeof section === "number") return section;
1873
+ if (typeof section === "boolean") return section;
1874
+ if (typeof (section === null || section === void 0 ? void 0 : section.nodeType) === "string") {
1875
+ const typedNode = section;
1876
+ const content = typedNode[typedNode.nodeType];
1877
+ if (typedNode.nodeType === NodeType.Translation || typedNode.nodeType === NodeType.Enumeration || typedNode.nodeType === NodeType.Condition || typedNode.nodeType === NodeType.Insertion || typedNode.nodeType === NodeType.Gender || typedNode.nodeType === NodeType.File || typedNode.nodeType === NodeType.Markdown) return content[Object.keys(content)[0]];
1878
+ if (typedNode.nodeType === NodeType.Nested) return;
1879
+ return content;
1880
+ }
1881
+ if (!section || typeof section !== "object") return section;
1882
+ if (Array.isArray(section)) return section[0];
1883
+ return section;
1884
+ };
1885
+
1886
+ //#endregion
1887
+ //#region src/utils/isValidReactElement.ts
1888
+ /**
1889
+ * Verifies the object is a ReactElement.
1890
+ * See https://reactjs.org/docs/react-api.html#isvalidelement
1891
+ * @param object
1892
+ * @return True if `object` is a ReactElement.
1893
+ * @final
1894
+ */
1895
+ const isValidElement = (object) => typeof object === "object" && typeof (object === null || object === void 0 ? void 0 : object.key) !== "undefined" && typeof (object === null || object === void 0 ? void 0 : object.props) !== "undefined";
1896
+
1897
+ //#endregion
1898
+ //#region src/dictionaryManipulator/getNodeType.ts
1899
+ /**
1900
+ * Type guard to check if content is a TypedNode
1901
+ */
1902
+ const isTypedNode = (content) => {
1903
+ return typeof content === "object" && content !== null && "nodeType" in content && typeof content.nodeType === "string";
1904
+ };
1905
+ /**
1906
+ * Type guard to check if content is a valid NodeType
1907
+ */
1908
+ const isValidNodeType = (nodeType) => {
1909
+ return Object.values(NodeType).includes(nodeType);
1910
+ };
1911
+ const getNodeType = (content) => {
1912
+ if (typeof content === "string") return NodeType.Text;
1913
+ if (isTypedNode(content)) {
1914
+ const nodeType = content.nodeType;
1915
+ if (isValidNodeType(nodeType)) return nodeType;
1916
+ return NodeType.Unknown;
1917
+ }
1918
+ if (Array.isArray(content)) return NodeType.Array;
1919
+ if (isValidElement(content)) return NodeType.ReactNode;
1920
+ if (typeof content === "number") return NodeType.Number;
1921
+ if (typeof content === "boolean") return NodeType.Boolean;
1922
+ if (content && typeof content === "object") return NodeType.Object;
1923
+ if (content === null) return NodeType.Null;
1924
+ return NodeType.Unknown;
1925
+ };
1926
+
1927
+ //#endregion
1928
+ //#region src/dictionaryManipulator/mergeDictionaries.ts
1929
+ const checkTypesMatch = (object1, object2, object2LocalId, dictionaryKey, path = []) => {
1930
+ const appLogger = getAppLogger(configuration);
1931
+ if (object1 === void 0 || object1 === null || object2 === void 0 || object2 === null) return;
1932
+ const type1 = getNodeType(object1);
1933
+ const type2 = getNodeType(object2);
1934
+ if (type1 === "unknown" || type2 === "unknown") return;
1935
+ if (type1 !== type2) {
1936
+ appLogger([`Error: Dictionary ${colorizeKey(dictionaryKey)} has a multiple content files with type mismatch at path "${path.join(".")}": Cannot merge ${type1} with ${type2} while merging ${object2LocalId}`], { level: "error" });
1937
+ return;
1938
+ }
1939
+ };
1940
+ const customMerge = (destination, source) => {
1941
+ if (destination === void 0 || destination === null) return source;
1942
+ if (source === void 0 || source === null) return destination;
1943
+ if (typeof destination !== "object" || typeof source !== "object") return destination;
1944
+ if (Array.isArray(destination) && Array.isArray(source)) return arrayMerge(destination, source);
1945
+ if (typeof destination === "object" && typeof source === "object") {
1946
+ const result = {};
1947
+ const allKeys = new Set([...Object.keys(destination), ...Object.keys(source)]);
1948
+ for (const key of allKeys) result[key] = customMerge(destination[key], source[key]);
1949
+ return result;
1950
+ }
1951
+ return destination;
1952
+ };
1953
+ const arrayMerge = (destinationArray, sourceArray) => {
1954
+ const destHasOnlyPrimitives = destinationArray.every((item) => typeof item !== "object" || item === null);
1955
+ const sourceHasOnlyPrimitives = sourceArray.every((item) => typeof item !== "object" || item === null);
1956
+ if (destHasOnlyPrimitives && sourceHasOnlyPrimitives) return sourceArray;
1957
+ const result = [];
1958
+ const maxLength = Math.max(destinationArray.length, sourceArray.length);
1959
+ for (let i = 0; i < maxLength; i++) {
1960
+ const destItem = destinationArray[i];
1961
+ const sourceItem = sourceArray[i];
1962
+ if (destItem === void 0 && sourceItem === void 0) {} else if (destItem === void 0) result.push(sourceItem);
1963
+ else if (sourceItem === void 0) result.push(destItem);
1964
+ else if (typeof destItem === "object" && typeof sourceItem === "object" && destItem !== null && sourceItem !== null) if ("key" in destItem && "key" in sourceItem && destItem.key === sourceItem.key) result.push(customMerge(destItem, sourceItem));
1965
+ else result.push(customMerge(destItem, sourceItem));
1966
+ else result.push(destItem);
1967
+ }
1968
+ return result;
1969
+ };
1970
+ const mergeDictionaries = (dictionaries) => {
1971
+ const localIds = Array.from(new Set(dictionaries.filter((dict) => dict.localId).map((dict) => dict.localId)));
1972
+ const dictionariesKeys = dictionaries.map((dict) => dict.key);
1973
+ if (new Set(dictionariesKeys).size !== 1) throw new Error("All dictionaries must have the same key");
1974
+ let mergedContent = dictionaries[0].content;
1975
+ for (let i = 1; i < dictionaries.length; i++) {
1976
+ const currentDictionary = getMultilingualDictionary(dictionaries[i]);
1977
+ checkTypesMatch(mergedContent, currentDictionary.content, currentDictionary.localId, currentDictionary.key, []);
1978
+ mergedContent = customMerge(mergedContent, currentDictionary.content);
1979
+ }
1980
+ return {
1981
+ key: dictionaries[0].key,
1982
+ content: mergedContent,
1983
+ localIds
1984
+ };
1985
+ };
1986
+
1987
+ //#endregion
1988
+ //#region src/dictionaryManipulator/orderDictionaries.ts
1989
+ /**
1990
+ * Orders dictionaries based on the dictionary priority strategy.
1991
+ *
1992
+ * @param dictionaries - Array of dictionaries to order
1993
+ * @param priorityStrategy - The priority strategy ('local_first' or 'distant_first')
1994
+ * @returns Ordered array of dictionaries
1995
+ */
1996
+ const orderDictionaries = (dictionaries, configuration$1 = configuration) => {
1997
+ const { editor } = configuration$1;
1998
+ const { dictionaryPriorityStrategy } = editor;
1999
+ if (dictionaries.length <= 1) return dictionaries;
2000
+ const withIndex = dictionaries.map((dictionary, index) => ({
2001
+ dictionary,
2002
+ index
2003
+ }));
2004
+ const getPriority = (dictionary) => {
2005
+ const p = dictionary.priority ?? 0;
2006
+ return Number.isFinite(p) ? p : 0;
2007
+ };
2008
+ const getLocationWeight = (d) => {
2009
+ const location = d.location;
2010
+ if (location === void 0) return 2;
2011
+ if (dictionaryPriorityStrategy === "distant_first") return location === "remote" ? 0 : 1;
2012
+ return location === "local" ? 0 : 1;
2013
+ };
2014
+ withIndex.sort((a, b) => {
2015
+ const aAuto = a.dictionary.filled ? 1 : 0;
2016
+ const bAuto = b.dictionary.filled ? 1 : 0;
2017
+ if (aAuto !== bAuto) return aAuto - bAuto;
2018
+ const aP = getPriority(a.dictionary);
2019
+ const bP = getPriority(b.dictionary);
2020
+ if (aP !== bP) return bP - aP;
2021
+ const aLocation = getLocationWeight(a.dictionary);
2022
+ const bLocation = getLocationWeight(b.dictionary);
2023
+ if (aLocation !== bLocation) return aLocation - bLocation;
2024
+ return a.index - b.index;
2025
+ });
2026
+ return withIndex.map(({ dictionary }) => dictionary);
2027
+ };
2028
+
2029
+ //#endregion
2030
+ //#region src/dictionaryManipulator/normalizeDictionary.ts
2031
+ const normalizeDictionary = (dictionary, configuration$1) => {
2032
+ const { locales } = configuration$1.internationalization;
2033
+ const parsedDictionary = JSON.parse(JSON.stringify(dictionary));
2034
+ if (dictionary.locale) return {
2035
+ ...dictionary,
2036
+ locale: void 0,
2037
+ content: translation({ [dictionary.locale]: dictionary.content })
2038
+ };
2039
+ const perLocaleContent = locales.reduce((acc, locale) => {
2040
+ acc[locale] = getPerLocaleDictionary(parsedDictionary, locale).content;
2041
+ return acc;
2042
+ }, {});
2043
+ return {
2044
+ ...dictionary,
2045
+ content: translation(perLocaleContent)
2046
+ };
2047
+ };
2048
+ const normalizeDictionaries = (dictionaries, configuration$1) => {
2049
+ return orderDictionaries(dictionaries, configuration$1).map((dictionary) => normalizeDictionary(dictionary, configuration$1));
2050
+ };
2051
+
2052
+ //#endregion
2053
+ //#region src/dictionaryManipulator/removeContentNodeByKeyPath.ts
2054
+ const removeContentNodeByKeyPath = (dictionaryContent, keyPath) => {
2055
+ let currentValue = dictionaryContent;
2056
+ let parentValue = null;
2057
+ let lastKey = null;
2058
+ for (const keyObj of keyPath) {
2059
+ parentValue = currentValue;
2060
+ if (keyObj.type === NodeType.Object || keyObj.type === NodeType.Array) {
2061
+ lastKey = keyObj.key;
2062
+ currentValue = currentValue[keyObj.key];
2063
+ }
2064
+ if (keyObj.type === NodeType.Translation || keyObj.type === NodeType.Enumeration || keyObj.type === NodeType.Condition) {
2065
+ lastKey = keyObj.type;
2066
+ currentValue = currentValue[keyObj.type][keyObj.key];
2067
+ }
2068
+ if (keyObj.type === NodeType.Markdown || keyObj.type === NodeType.ReactNode || keyObj.type === NodeType.Insertion || keyObj.type === NodeType.File) {
2069
+ lastKey = keyObj.type;
2070
+ currentValue = currentValue[keyObj.type];
2071
+ }
2072
+ }
2073
+ if (parentValue && lastKey !== null) if (Array.isArray(parentValue)) parentValue.splice(lastKey, 1);
2074
+ else delete parentValue[lastKey];
2075
+ return dictionaryContent;
2076
+ };
2077
+
2078
+ //#endregion
2079
+ //#region src/dictionaryManipulator/renameContentNodeByKeyPath.ts
2080
+ const renameContentNodeByKeyPath = (dictionaryContent, newKey, keyPath) => {
2081
+ let currentValue = dictionaryContent;
2082
+ let parentValue = null;
2083
+ let lastKey = null;
2084
+ for (const keyObj of keyPath) {
2085
+ parentValue = currentValue;
2086
+ if (keyObj.type === NodeType.Object || keyObj.type === NodeType.Array) {
2087
+ lastKey = keyObj.key;
2088
+ currentValue = currentValue[keyObj.key];
2089
+ }
2090
+ if (keyObj.type === NodeType.Translation || keyObj.type === NodeType.Enumeration || keyObj.type === NodeType.Condition) {
2091
+ lastKey = keyObj.type;
2092
+ currentValue = currentValue[keyObj.type][keyObj.key];
2093
+ }
2094
+ if (keyObj.type === NodeType.Markdown || keyObj.type === NodeType.ReactNode || keyObj.type === NodeType.Insertion || keyObj.type === NodeType.File) {
2095
+ lastKey = keyObj.type;
2096
+ currentValue = currentValue[keyObj.type];
2097
+ }
2098
+ }
2099
+ if (parentValue && lastKey !== null) if (Array.isArray(parentValue)) parentValue[lastKey] = currentValue;
2100
+ else {
2101
+ const newParentValue = {};
2102
+ for (const key of Object.keys(parentValue)) if (key === lastKey && typeof newKey !== "undefined") newParentValue[newKey] = currentValue;
2103
+ else newParentValue[key] = parentValue[key];
2104
+ Object.keys(parentValue).forEach((key) => {
2105
+ delete parentValue[key];
2106
+ });
2107
+ Object.assign(parentValue, newParentValue);
2108
+ }
2109
+ return dictionaryContent;
2110
+ };
2111
+
2112
+ //#endregion
2113
+ //#region src/dictionaryManipulator/updateNodeChildren.ts
2114
+ const updateNodeChildren = (section, newChildren) => {
2115
+ if (typeof section === "string") return newChildren;
2116
+ if (typeof section === "number") return newChildren;
2117
+ if (typeof section === "boolean") return newChildren;
2118
+ if (typeof (section === null || section === void 0 ? void 0 : section.nodeType) === "string") {
2119
+ const typedNode = section;
2120
+ const content = typedNode[typedNode.nodeType];
2121
+ if (typedNode.nodeType === NodeType.Translation || typedNode.nodeType === NodeType.Enumeration || typedNode.nodeType === NodeType.Condition) {
2122
+ const newContent = Object.entries(content).reduce((acc, [key]) => {
2123
+ acc[key] = newChildren;
2124
+ return acc;
2125
+ }, {});
2126
+ return {
2127
+ ...typedNode,
2128
+ [typedNode.nodeType]: newContent
2129
+ };
2130
+ }
2131
+ if (typedNode.nodeType === NodeType.Nested) return typedNode;
2132
+ return {
2133
+ ...typedNode,
2134
+ [typedNode.nodeType]: newChildren
2135
+ };
2136
+ }
2137
+ if (!section || typeof section !== "object") return newChildren;
2138
+ if (Array.isArray(section)) return section.map(() => newChildren);
2139
+ return Object.entries(section).reduce((acc, [key]) => ({
2140
+ ...acc,
2141
+ [key]: newChildren
2142
+ }), {});
2143
+ };
2144
+
2145
+ //#endregion
2146
+ //#region src/utils/intl.ts
2147
+ const cacheKey = (locales, options) => JSON.stringify([locales, options]);
2148
+ const createCachedConstructor = (Ctor) => {
2149
+ const cache = /* @__PURE__ */ new Map();
2150
+ function Wrapped(locales, options) {
2151
+ var _Intl;
2152
+ if (Ctor.name === "DisplayNames" && typeof ((_Intl = Intl) === null || _Intl === void 0 ? void 0 : _Intl.DisplayNames) !== "function") {
2153
+ if (process.env.NODE_ENV === "development") console.warn([
2154
+ `// Intl.DisplayNames is not supported; falling back to raw locale (${locales}). `,
2155
+ `// Consider adding a polyfill as https://formatjs.io/docs/polyfills/intl-displaynames/`,
2156
+ ``,
2157
+ `import 'intl';`,
2158
+ `import '@formatjs/intl-getcanonicallocales/polyfill';`,
2159
+ `import '@formatjs/intl-locale/polyfill';`,
2160
+ `import '@formatjs/intl-pluralrules/polyfill';`,
2161
+ `import '@formatjs/intl-displaynames/polyfill';`,
2162
+ `import '@formatjs/intl-listformat/polyfill';`,
2163
+ `import '@formatjs/intl-numberformat/polyfill';`,
2164
+ `import '@formatjs/intl-relativetimeformat/polyfill';`,
2165
+ `import '@formatjs/intl-datetimeformat/polyfill';`,
2166
+ ``,
2167
+ `// Optionally add locale data`,
2168
+ `import '@formatjs/intl-pluralrules/locale-data/fr';`,
2169
+ `import '@formatjs/intl-numberformat/locale-data/fr';`,
2170
+ `import '@formatjs/intl-datetimeformat/locale-data/fr';`
2171
+ ].join("\n"));
2172
+ return locales;
2173
+ }
2174
+ const key = cacheKey(locales ?? Locales.ENGLISH, options);
2175
+ let instance = cache.get(key);
2176
+ if (!instance) {
2177
+ instance = new Ctor(locales, options);
2178
+ cache.set(key, instance);
2179
+ }
2180
+ return instance;
2181
+ }
2182
+ Wrapped.prototype = Ctor.prototype;
2183
+ return Wrapped;
2184
+ };
2185
+ const createCachedIntl = () => new Proxy(Intl, { get: (target, prop, receiver) => {
2186
+ const value = Reflect.get(target, prop, receiver);
2187
+ return typeof value === "function" && /^[A-Z]/.test(String(prop)) ? createCachedConstructor(value) : value;
2188
+ } });
2189
+ const CachedIntl = createCachedIntl();
2190
+
2191
+ //#endregion
2192
+ //#region src/formatters/compact.ts
2193
+ /**
2194
+ * Formats a numeric value using compact notation (e.g., 1K, 1M, 1B)
2195
+ * based on locale and formatting options.
2196
+ *
2197
+ * @example
2198
+ * compact({ value: 1200 }); // "1.2K"
2199
+ *
2200
+ * @example
2201
+ * compact({ value: "1000000", locale: Locales.FRENCH, compactDisplay: "long" });
2202
+ * // "1 million"
2203
+ */
2204
+ const compact = (value, options) => {
2205
+ var _configuration$intern;
2206
+ return new CachedIntl.NumberFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), {
2207
+ ...options,
2208
+ notation: "compact"
2209
+ }).format(Number(value));
2210
+ };
2211
+
2212
+ //#endregion
2213
+ //#region src/formatters/currency.ts
2214
+ /**
2215
+ * Formats a numeric or string value into a localized currency string using the Intl API.
2216
+ *
2217
+ * @example
2218
+ * currency({ value: 1234.5, currency: 'EUR' });
2219
+ * // "€1,234.50"
2220
+ *
2221
+ * @example
2222
+ * currency({ value: "5000", locale: Locales.FRENCH, currency: "CAD", currencyDisplay: "code" });
2223
+ * // "5 000,00 CAD"
2224
+ */
2225
+ const currency = (value, options) => {
2226
+ var _configuration$intern;
2227
+ return new CachedIntl.NumberFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), {
2228
+ style: "currency",
2229
+ currency: (options === null || options === void 0 ? void 0 : options.currency) ?? "USD",
2230
+ currencyDisplay: (options === null || options === void 0 ? void 0 : options.currencyDisplay) ?? "symbol",
2231
+ minimumFractionDigits: (options === null || options === void 0 ? void 0 : options.minimumFractionDigits) ?? 2,
2232
+ maximumFractionDigits: (options === null || options === void 0 ? void 0 : options.maximumFractionDigits) ?? 2,
2233
+ ...options
2234
+ }).format(Number(value));
2235
+ };
2236
+
2237
+ //#endregion
2238
+ //#region src/formatters/date.ts
2239
+ const presets = {
2240
+ short: {
2241
+ year: "2-digit",
2242
+ month: "2-digit",
2243
+ day: "2-digit",
2244
+ hour: "2-digit",
2245
+ minute: "2-digit"
2246
+ },
2247
+ long: {
2248
+ year: "numeric",
2249
+ month: "long",
2250
+ day: "numeric",
2251
+ hour: "numeric",
2252
+ minute: "numeric"
2253
+ },
2254
+ full: {
2255
+ year: "numeric",
2256
+ month: "long",
2257
+ day: "numeric",
2258
+ hour: "numeric",
2259
+ minute: "numeric",
2260
+ hour12: false
2261
+ },
2262
+ dateOnly: {
2263
+ year: "numeric",
2264
+ month: "short",
2265
+ day: "numeric"
2266
+ },
2267
+ timeOnly: {
2268
+ hour: "numeric",
2269
+ minute: "numeric",
2270
+ second: "numeric"
2271
+ }
2272
+ };
2273
+ /**
2274
+ * Formats a date/time value into a localized string using Intl.DateTimeFormat.
2275
+ *
2276
+ * @example
2277
+ * date({ date: new Date(), options: "short" });
2278
+ * // "08/02/25, 14:30"
2279
+ *
2280
+ * @example
2281
+ * date({ date: "2025-08-02T14:30:00Z", locale: Locales.FRENCH, options: { month: "long", day: "numeric" } });
2282
+ * // "2 août"
2283
+ */
2284
+ const date = (date$1, options) => {
2285
+ var _configuration$intern;
2286
+ const dateTime = new Date(date$1);
2287
+ const resolvedOptions = typeof options === "string" ? presets[options] ?? {} : options;
2288
+ return new CachedIntl.DateTimeFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), resolvedOptions).format(dateTime);
2289
+ };
2290
+
2291
+ //#endregion
2292
+ //#region src/formatters/list.ts
2293
+ /**
2294
+ * Formats an array of values into a localized list string using the Intl API.
2295
+ *
2296
+ * @example
2297
+ * list(['apple', 'banana', 'orange']);
2298
+ * // "apple, banana, and orange"
2299
+ *
2300
+ * @example
2301
+ * list(['red', 'green', 'blue'], { locale: Locales.FRENCH, type: 'disjunction' });
2302
+ * // "rouge, vert ou bleu"
2303
+ *
2304
+ * @example
2305
+ * list([1, 2, 3], { type: 'unit' });
2306
+ * // "1, 2, 3"
2307
+ */
2308
+ const list = (values, options) => {
2309
+ var _configuration$intern;
2310
+ return new CachedIntl.ListFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), {
2311
+ type: (options === null || options === void 0 ? void 0 : options.type) ?? "conjunction",
2312
+ style: (options === null || options === void 0 ? void 0 : options.style) ?? "long",
2313
+ ...options
2314
+ }).format(values.map(String));
2315
+ };
2316
+
2317
+ //#endregion
2318
+ //#region src/formatters/number.ts
2319
+ /**
2320
+ * Formats a numeric value using locale-aware formatting.
2321
+ *
2322
+ * @example
2323
+ * number({ value: 123456.789 }); // "123,456.789"
2324
+ * number({ value: "1000000", locale: Locales.FRENCH }); // "1 000 000"
2325
+ */
2326
+ const number = (value, options) => {
2327
+ var _configuration$intern;
2328
+ return new CachedIntl.NumberFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), options).format(Number(value));
2329
+ };
2330
+
2331
+ //#endregion
2332
+ //#region src/formatters/percentage.ts
2333
+ /**
2334
+ * Formats a number as a percentage string (e.g., 0.25 → "25%").
2335
+ *
2336
+ * @example
2337
+ * percentage({ value: 0.25 }) // "25%"
2338
+ * percentage({ value: 0.25, minimumFractionDigits: 2 }) // "25.00%"
2339
+ */
2340
+ const percentage = (value, options) => {
2341
+ var _configuration$intern;
2342
+ let numericValue = Number(value);
2343
+ if (numericValue > 1) numericValue /= 100;
2344
+ return new CachedIntl.NumberFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), {
2345
+ style: "percent",
2346
+ ...options
2347
+ }).format(Number(numericValue));
2348
+ };
2349
+
2350
+ //#endregion
2351
+ //#region src/formatters/relativeTime.ts
2352
+ /**
2353
+ * Calculate the difference between 2 dates in the given unit.
2354
+ */
2355
+ const diffInUnit = (from, to, unit) => {
2356
+ const sec = (to.getTime() - from.getTime()) / 1e3;
2357
+ switch (unit) {
2358
+ case "second": return sec;
2359
+ case "minute": return sec / 60;
2360
+ case "hour": return sec / 3600;
2361
+ case "day": return sec / 86400;
2362
+ case "month": return sec / (30 * 86400);
2363
+ case "quarter": return sec / (90 * 86400);
2364
+ case "year": return sec / (365 * 86400);
2365
+ default: return sec;
2366
+ }
2367
+ };
2368
+ const relativeTime = (from, to = /* @__PURE__ */ new Date(), options) => {
2369
+ var _configuration$intern;
2370
+ const fromDate = new Date(from);
2371
+ const toDate = new Date(to);
2372
+ const unit = (options === null || options === void 0 ? void 0 : options.unit) ?? "second";
2373
+ const value = diffInUnit(fromDate, toDate, unit);
2374
+ return new CachedIntl.RelativeTimeFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), options).format(Math.round(value), unit);
2375
+ };
2376
+
2377
+ //#endregion
2378
+ //#region src/formatters/units.ts
2379
+ /**
2380
+ * Formats a numeric value as a localized unit string.
2381
+ *
2382
+ * @example
2383
+ * units({ value: 5, unit: "kilometer", unitDisplay: "long", locale: "en-GB" })
2384
+ * // "5 kilometers"
2385
+ */
2386
+ const units = (value, options) => {
2387
+ var _configuration$intern;
2388
+ return new CachedIntl.NumberFormat((options === null || options === void 0 ? void 0 : options.locale) ?? (configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.defaultLocale), {
2389
+ style: "unit",
2390
+ unit: (options === null || options === void 0 ? void 0 : options.unit) ?? "day",
2391
+ unitDisplay: (options === null || options === void 0 ? void 0 : options.unitDisplay) ?? "short",
2392
+ useGrouping: (options === null || options === void 0 ? void 0 : options.useGrouping) ?? false
2393
+ }).format(Number(value));
2394
+ };
2395
+
2396
+ //#endregion
2397
+ //#region src/getStorageAttributes.ts
2398
+ /**
2399
+ * Creates a cookie entry with default values for missing attributes
2400
+ */
2401
+ const createCookieEntry = (options) => {
2402
+ const { name, path, expires, domain, secure, sameSite, httpOnly } = options ?? {};
2403
+ return {
2404
+ name: name ?? DefaultValues.Routing.COOKIE_NAME,
2405
+ attributes: {
2406
+ path,
2407
+ expires,
2408
+ domain,
2409
+ secure,
2410
+ sameSite,
2411
+ httpOnly
2412
+ }
2413
+ };
2414
+ };
2415
+ /**
2416
+ * Creates a web storage entry (localStorage or sessionStorage) with default name
2417
+ */
2418
+ const createWebStorageEntry = (options) => {
2419
+ const { name } = options ?? {};
2420
+ return { name: name ?? DefaultValues.Routing.LOCALE_STORAGE_NAME };
2421
+ };
2422
+ /**
2423
+ * Creates a header entry with default name
2424
+ */
2425
+ const createHeaderEntry = (options) => {
2426
+ const { name } = options ?? {};
2427
+ return { name: name ?? DefaultValues.Routing.HEADER_NAME };
2428
+ };
2429
+ /**
2430
+ * Determines if a storage entry is a cookie based on its properties
2431
+ */
2432
+ const isCookieEntry = (entry) => {
2433
+ return entry.type === "cookie" || "sameSite" in entry || "httpOnly" in entry || "secure" in entry;
2434
+ };
2435
+ /**
2436
+ * Determines the storage type from a string literal
2437
+ */
2438
+ const isStorageType = (value) => {
2439
+ return value === "cookie" || value === "localStorage" || value === "sessionStorage" || value === "header";
2440
+ };
2441
+ /**
2442
+ * Processes a single storage entry and returns the appropriate storage attributes
2443
+ */
2444
+ const processStorageEntry = (entry) => {
2445
+ if (typeof entry === "string") {
2446
+ if (!isStorageType(entry)) return {
2447
+ cookies: [],
2448
+ localStorage: [],
2449
+ sessionStorage: [],
2450
+ headers: []
2451
+ };
2452
+ if (entry === "cookie") return { cookies: [createCookieEntry()] };
2453
+ if (entry === "localStorage") return { localStorage: [createWebStorageEntry()] };
2454
+ if (entry === "sessionStorage") return { sessionStorage: [createWebStorageEntry()] };
2455
+ if (entry === "header") return { headers: [createHeaderEntry()] };
2456
+ }
2457
+ if (typeof entry === "object" && entry !== null) {
2458
+ const typedEntry = entry;
2459
+ if (isCookieEntry(typedEntry)) return { cookies: [createCookieEntry(typedEntry)] };
2460
+ if ("type" in typedEntry && typedEntry.type === "localStorage") {
2461
+ const { name: name$1,...rest$1 } = typedEntry;
2462
+ return { localStorage: [createWebStorageEntry({
2463
+ name: name$1,
2464
+ ...rest$1
2465
+ })] };
2466
+ }
2467
+ if ("type" in typedEntry && typedEntry.type === "sessionStorage") {
2468
+ const { name: name$1,...rest$1 } = typedEntry;
2469
+ return { sessionStorage: [createWebStorageEntry({
2470
+ name: name$1,
2471
+ ...rest$1
2472
+ })] };
2473
+ }
2474
+ if ("type" in typedEntry && typedEntry.type === "header") {
2475
+ const { name: name$1,...rest$1 } = typedEntry;
2476
+ return { headers: [createHeaderEntry({
2477
+ name: name$1,
2478
+ ...rest$1
2479
+ })] };
2480
+ }
2481
+ const { name,...rest } = typedEntry;
2482
+ return { localStorage: [createWebStorageEntry({
2483
+ name,
2484
+ ...rest
2485
+ })] };
2486
+ }
2487
+ return {
2488
+ cookies: [],
2489
+ localStorage: [],
2490
+ sessionStorage: [],
2491
+ headers: []
2492
+ };
2493
+ };
2494
+ /**
2495
+ * Merges multiple partial storage attributes into a single result
2496
+ */
2497
+ const mergeStorageAttributes = (accumulated, partial) => {
2498
+ return {
2499
+ cookies: [...accumulated.cookies, ...partial.cookies ?? []],
2500
+ localStorage: [...accumulated.localStorage, ...partial.localStorage ?? []],
2501
+ sessionStorage: [...accumulated.sessionStorage, ...partial.sessionStorage ?? []],
2502
+ headers: [...accumulated.headers, ...partial.headers ?? []]
2503
+ };
2504
+ };
2505
+ /**
2506
+ * Extracts and normalizes storage configuration into separate arrays for each storage type
2507
+ *
2508
+ * @param options - The storage configuration from IntlayerConfig
2509
+ * @returns An object containing arrays for cookies, localStorage, and sessionStorage
2510
+ */
2511
+ const getStorageAttributes = (options) => {
2512
+ const emptyResult = {
2513
+ cookies: [],
2514
+ localStorage: [],
2515
+ sessionStorage: [],
2516
+ headers: []
2517
+ };
2518
+ if (options === false || options === void 0) return emptyResult;
2519
+ if (Array.isArray(options)) return options.reduce((acc, entry) => {
2520
+ return mergeStorageAttributes(acc, processStorageEntry(entry));
2521
+ }, emptyResult);
2522
+ return mergeStorageAttributes(emptyResult, processStorageEntry(options));
2523
+ };
2524
+
2525
+ //#endregion
2526
+ //#region src/utils/localeStorage.ts
2527
+ const buildCookieString = (name, value, attributes) => {
2528
+ const parts = [`${name}=${encodeURIComponent(value)}`];
2529
+ if (attributes.path) parts.push(`Path=${attributes.path}`);
2530
+ if (attributes.domain) parts.push(`Domain=${attributes.domain}`);
2531
+ if (attributes.expires instanceof Date) parts.push(`Expires=${attributes.expires.toUTCString()}`);
2532
+ if (attributes.secure) parts.push("Secure");
2533
+ if (attributes.sameSite) parts.push(`SameSite=${attributes.sameSite}`);
2534
+ return parts.join("; ");
2535
+ };
2536
+ /**
2537
+ * Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).
2538
+ * The function checks storage locations in order of priority as defined in the configuration.
2539
+ *
2540
+ * @returns The locale if found in any storage, or undefined if not found
2541
+ */
2542
+ const getLocaleFromStorage = (options) => {
2543
+ const { routing, internationalization } = configuration;
2544
+ const { locales } = internationalization;
2545
+ const { storage } = routing;
2546
+ if (storage === false || (options === null || options === void 0 ? void 0 : options.isCookieEnabled) === false) return void 0;
2547
+ const storageAttributes = getStorageAttributes(storage);
2548
+ const isValidLocale = (value) => {
2549
+ if (!value) return false;
2550
+ return locales.includes(value);
2551
+ };
2552
+ const readCookie = (name) => {
2553
+ try {
2554
+ var _options$getCookie;
2555
+ const fromOption = options === null || options === void 0 || (_options$getCookie = options.getCookie) === null || _options$getCookie === void 0 ? void 0 : _options$getCookie.call(options, name);
2556
+ if (fromOption !== null) return fromOption;
2557
+ } catch {}
2558
+ try {
2559
+ const cookieString = document.cookie ?? "";
2560
+ if (!cookieString) return;
2561
+ const pairs = cookieString.split(";");
2562
+ for (let i = 0; i < pairs.length; i++) {
2563
+ const part = pairs[i].trim();
2564
+ if (!part) continue;
2565
+ const equalIndex = part.indexOf("=");
2566
+ if ((equalIndex >= 0 ? part.substring(0, equalIndex) : part) === name) {
2567
+ const rawValue = equalIndex >= 0 ? part.substring(equalIndex + 1) : "";
2568
+ try {
2569
+ return decodeURIComponent(rawValue);
2570
+ } catch {
2571
+ return rawValue;
2572
+ }
2573
+ }
2574
+ }
2575
+ } catch {}
2576
+ };
2577
+ for (let i = 0; i < storageAttributes.cookies.length; i++) {
2578
+ const { name } = storageAttributes.cookies[i];
2579
+ const value = readCookie(name);
2580
+ if (isValidLocale(value)) return value;
2581
+ }
2582
+ for (let i = 0; i < storageAttributes.localStorage.length; i++) {
2583
+ const { name } = storageAttributes.localStorage[i];
2584
+ try {
2585
+ var _options$getLocaleSto;
2586
+ const value = options === null || options === void 0 || (_options$getLocaleSto = options.getLocaleStorage) === null || _options$getLocaleSto === void 0 ? void 0 : _options$getLocaleSto.call(options, name);
2587
+ if (isValidLocale(value)) return value;
2588
+ } catch {}
2589
+ }
2590
+ for (let i = 0; i < storageAttributes.sessionStorage.length; i++) {
2591
+ const { name } = storageAttributes.sessionStorage[i];
2592
+ try {
2593
+ var _options$getSessionSt;
2594
+ const value = options === null || options === void 0 || (_options$getSessionSt = options.getSessionStorage) === null || _options$getSessionSt === void 0 ? void 0 : _options$getSessionSt.call(options, name);
2595
+ if (isValidLocale(value)) return value;
2596
+ } catch {}
2597
+ }
2598
+ for (let i = 0; i < storageAttributes.headers.length; i++) {
2599
+ const { name } = storageAttributes.headers[i];
2600
+ try {
2601
+ var _options$getHeader;
2602
+ const value = options === null || options === void 0 || (_options$getHeader = options.getHeader) === null || _options$getHeader === void 0 ? void 0 : _options$getHeader.call(options, name);
2603
+ if (isValidLocale(value)) return value;
2604
+ } catch {}
2605
+ }
2606
+ };
2607
+ /**
2608
+ * Stores the locale in various storage mechanisms (cookies, localStorage, sessionStorage, headers).
2609
+ * The function writes to all configured storage locations according to their attributes.
2610
+ * Respects overwrite flags for localStorage and sessionStorage.
2611
+ *
2612
+ * @param locale - The locale to store
2613
+ */
2614
+ const setLocaleInStorage = (locale, options) => {
2615
+ if (configuration.routing.storage === false || (options === null || options === void 0 ? void 0 : options.isCookieEnabled) === false) return;
2616
+ const storageAttributes = getStorageAttributes(configuration.routing.storage);
2617
+ for (let i = 0; i < storageAttributes.cookies.length; i++) {
2618
+ const { name, attributes } = storageAttributes.cookies[i];
2619
+ try {
2620
+ if (options === null || options === void 0 ? void 0 : options.setCookieStore) {
2621
+ var _options$setCookieSto;
2622
+ options === null || options === void 0 || (_options$setCookieSto = options.setCookieStore) === null || _options$setCookieSto === void 0 || _options$setCookieSto.call(options, name, locale, {
2623
+ ...attributes,
2624
+ expires: attributes.expires instanceof Date ? attributes.expires.getTime() : attributes.expires
2625
+ });
2626
+ }
2627
+ } catch {
2628
+ try {
2629
+ if (options === null || options === void 0 ? void 0 : options.setCookieString) {
2630
+ var _options$setCookieStr;
2631
+ const cookieString = buildCookieString(name, locale, attributes);
2632
+ options === null || options === void 0 || (_options$setCookieStr = options.setCookieString) === null || _options$setCookieStr === void 0 || _options$setCookieStr.call(options, name, cookieString);
2633
+ }
2634
+ } catch {}
2635
+ }
2636
+ }
2637
+ if (options === null || options === void 0 ? void 0 : options.setLocaleStorage) for (let i = 0; i < storageAttributes.localStorage.length; i++) {
2638
+ const { name } = storageAttributes.localStorage[i];
2639
+ try {
2640
+ var _options$setLocaleSto;
2641
+ if (!((options === null || options === void 0 ? void 0 : options.overwrite) ?? true) && (options === null || options === void 0 ? void 0 : options.getLocaleStorage)) {
2642
+ var _options$getLocaleSto2;
2643
+ if (options === null || options === void 0 || (_options$getLocaleSto2 = options.getLocaleStorage) === null || _options$getLocaleSto2 === void 0 ? void 0 : _options$getLocaleSto2.call(options, name)) continue;
2644
+ }
2645
+ options === null || options === void 0 || (_options$setLocaleSto = options.setLocaleStorage) === null || _options$setLocaleSto === void 0 || _options$setLocaleSto.call(options, name, locale);
2646
+ } catch {}
2647
+ }
2648
+ if (options === null || options === void 0 ? void 0 : options.setSessionStorage) for (let i = 0; i < storageAttributes.sessionStorage.length; i++) {
2649
+ const { name } = storageAttributes.sessionStorage[i];
2650
+ try {
2651
+ var _options$setSessionSt;
2652
+ if (!((options === null || options === void 0 ? void 0 : options.overwrite) ?? true) && (options === null || options === void 0 ? void 0 : options.getSessionStorage)) {
2653
+ var _options$getSessionSt2;
2654
+ if (options === null || options === void 0 || (_options$getSessionSt2 = options.getSessionStorage) === null || _options$getSessionSt2 === void 0 ? void 0 : _options$getSessionSt2.call(options, name)) continue;
2655
+ }
2656
+ options === null || options === void 0 || (_options$setSessionSt = options.setSessionStorage) === null || _options$setSessionSt === void 0 || _options$setSessionSt.call(options, name, locale);
2657
+ } catch {}
2658
+ }
2659
+ if (options === null || options === void 0 ? void 0 : options.setHeader) for (let i = 0; i < storageAttributes.headers.length; i++) {
2660
+ const { name } = storageAttributes.headers[i];
2661
+ try {
2662
+ var _options$setHeader;
2663
+ options === null || options === void 0 || (_options$setHeader = options.setHeader) === null || _options$setHeader === void 0 || _options$setHeader.call(options, name, locale);
2664
+ } catch {}
2665
+ }
2666
+ };
2667
+ /**
2668
+ * Utility object to get and set the locale in the storage by considering the configuration
2669
+ *
2670
+ * @property getLocale - Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).
2671
+ * Retrieves the locale from various storage mechanisms (cookies, localStorage, sessionStorage, headers).
2672
+ * The function checks storage locations in order of priority as defined in the configuration.
2673
+ *
2674
+ * @property setLocale - Stores the locale in various storage mechanisms (cookies, localStorage, sessionStorage, headers).
2675
+ * The function writes to all configured storage locations according to their attributes.
2676
+ * Respects overwrite flags for localStorage and sessionStorage.
2677
+ *
2678
+ * @returns The locale if found in any storage, or undefined if not found
2679
+ */
2680
+ const LocaleStorage = (options) => ({
2681
+ getLocale: () => getLocaleFromStorage(options),
2682
+ setLocale: (locale) => setLocaleInStorage(locale, options)
2683
+ });
2684
+
2685
+ //#endregion
2686
+ //#region src/localization/localeResolver.ts
2687
+ var _configuration$intern2$2;
2688
+ /**
2689
+ * Resolves the most specific locale from a user-provided list,
2690
+ * or falls back to the default locale if no match is found.
2691
+ */
2692
+ const localeResolver = (selectedLocale, locales = (() => {
2693
+ var _configuration$intern;
2694
+ return configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.locales;
2695
+ })(), defaultLocale = configuration === null || configuration === void 0 || (_configuration$intern2$2 = configuration.internationalization) === null || _configuration$intern2$2 === void 0 ? void 0 : _configuration$intern2$2.defaultLocale) => {
2696
+ const requestedLocales = [selectedLocale].flat();
2697
+ const normalize = (locale) => locale.trim().toLowerCase();
2698
+ try {
2699
+ for (const requested of requestedLocales) {
2700
+ const normalizedRequested = normalize(requested);
2701
+ const exactMatch = locales.find((loc) => normalize(loc) === normalizedRequested);
2702
+ if (exactMatch) return exactMatch;
2703
+ const [requestedLang] = normalizedRequested.split("-");
2704
+ const partialMatch = locales.find((loc) => normalize(loc).split("-")[0] === requestedLang);
2705
+ if (partialMatch) return partialMatch;
2706
+ }
2707
+ } catch (_error) {}
2708
+ return defaultLocale;
2709
+ };
2710
+
2711
+ //#endregion
2712
+ //#region src/localization/localeDetector.ts
2713
+ /**
2714
+ * Module variables.
2715
+ */
2716
+ const simpleLanguageRegExp = /^\s*([^\s\-;]+)(?:-([^\s;]+))?\s*(?:;(.*))?$/;
2717
+ /**
2718
+ * Parse the Accept-Language header.
2719
+ */
2720
+ const parseAcceptLanguage = (accept) => {
2721
+ const rawAccepts = accept.split(",");
2722
+ const accepts = [];
2723
+ for (let i = 0; i < rawAccepts.length; i++) {
2724
+ const language = parseLanguage(rawAccepts[i].trim(), i);
2725
+ if (language) accepts.push(language);
2726
+ }
2727
+ return accepts;
2728
+ };
2729
+ /**
2730
+ * Parse a language from the Accept-Language header.
2731
+ */
2732
+ const parseLanguage = (str, i) => {
2733
+ const match = simpleLanguageRegExp.exec(str);
2734
+ if (!match) return null;
2735
+ const prefix = match[1];
2736
+ const suffix = match[2];
2737
+ let full = prefix;
2738
+ if (suffix) full = `${prefix}-${suffix}`;
2739
+ let q = 1;
2740
+ if (match[3]) {
2741
+ const params = match[3].split(";");
2742
+ for (let j = 0; j < params.length; j++) {
2743
+ const p = params[j].split("=");
2744
+ if (p[0] === "q") q = parseFloat(p[1]);
2745
+ }
2746
+ }
2747
+ return {
2748
+ prefix,
2749
+ suffix,
2750
+ q,
2751
+ i,
2752
+ full
2753
+ };
2754
+ };
2755
+ /**
2756
+ * Get the priority of a language.
2757
+ */
2758
+ const getLanguagePriority = (language, accepted, index) => {
2759
+ let priority = {
2760
+ o: -1,
2761
+ q: 0,
2762
+ s: 0,
2763
+ i: index
2764
+ };
2765
+ for (let i = 0; i < accepted.length; i++) {
2766
+ const spec = specify(language, accepted[i], index);
2767
+ if (spec && (priority.s - spec.s || priority.q - spec.q || priority.o - spec.o) < 0) priority = spec;
2768
+ }
2769
+ return priority;
2770
+ };
2771
+ /**
2772
+ * Get the specificity of the language.
2773
+ */
2774
+ const specify = (language, spec, index) => {
2775
+ const p = parseLanguage(language, index);
2776
+ if (!p) return null;
2777
+ let s = 0;
2778
+ if (spec.full.toLowerCase() === p.full.toLowerCase()) s |= 4;
2779
+ else if (spec.prefix.toLowerCase() === p.full.toLowerCase()) s |= 2;
2780
+ else if (spec.full.toLowerCase() === p.prefix.toLowerCase()) s |= 1;
2781
+ else if (spec.full !== "*") return null;
2782
+ return {
2783
+ i: index,
2784
+ o: spec.i,
2785
+ q: spec.q,
2786
+ s
2787
+ };
2788
+ };
2789
+ /**
2790
+ * Get the preferred languages from an Accept-Language header.
2791
+ */
2792
+ const preferredLanguages = (accept, provided) => {
2793
+ const accepts = parseAcceptLanguage(accept === void 0 ? "*" : accept ?? "");
2794
+ if (!provided) return accepts.filter(isQuality).sort(compareSpecs).map(getFullLanguage);
2795
+ const priorities = provided.map((type, index) => getLanguagePriority(type, accepts, index));
2796
+ return priorities.filter(isQuality).sort(compareSpecs).map((priority) => provided[priorities.indexOf(priority)]);
2797
+ };
2798
+ /**
2799
+ * Compare two specs.
2800
+ */
2801
+ const compareSpecs = (a, b) => b.q - a.q || (b.s ?? 0) - (a.s ?? 0) || (a.o ?? 0) - (b.o ?? 0) || a.i - b.i || 0;
2802
+ /**
2803
+ * Get full language string.
2804
+ */
2805
+ const getFullLanguage = (spec) => spec.full;
2806
+ /**
2807
+ * Check if a spec has any quality.
2808
+ */
2809
+ const isQuality = (spec) => spec.q > 0;
2810
+ /**
2811
+ * Detects the locale from the request headers
2812
+ *
2813
+ * Headers are provided by the browser and can be used to determine the user's preferred language
2814
+ */
2815
+ const localeDetector = (headers, locales, defaultLocale) => {
2816
+ const accept = headers["accept-language"];
2817
+ return localeResolver(preferredLanguages(accept), locales, defaultLocale);
2818
+ };
2819
+
2820
+ //#endregion
2821
+ //#region src/localization/getBrowserLocale.tsx
2822
+ let LanguageDetector = /* @__PURE__ */ function(LanguageDetector$1) {
2823
+ LanguageDetector$1["Querystring"] = "querystring";
2824
+ LanguageDetector$1["Storage"] = "storage";
2825
+ LanguageDetector$1["Navigator"] = "navigator";
2826
+ LanguageDetector$1["HtmlTag"] = "htmlTag";
2827
+ return LanguageDetector$1;
2828
+ }({});
2829
+ const localeStorageOptions = {
2830
+ getCookie: (name) => {
2831
+ var _document$cookie$spli;
2832
+ return (_document$cookie$spli = document.cookie.split(";").find((c) => c.trim().startsWith(`${name}=`))) === null || _document$cookie$spli === void 0 ? void 0 : _document$cookie$spli.split("=")[1];
2833
+ },
2834
+ getLocaleStorage: (name) => localStorage.getItem(name),
2835
+ getSessionStorage: (name) => sessionStorage.getItem(name),
2836
+ isCookieEnabled: true,
2837
+ setCookieStore: (name, value, attributes) => cookieStore.set({
2838
+ name,
2839
+ value,
2840
+ path: attributes.path,
2841
+ domain: attributes.domain,
2842
+ expires: attributes.expires,
2843
+ sameSite: attributes.sameSite
2844
+ }),
2845
+ setCookieString: (cookie) => {
2846
+ document.cookie = cookie;
2847
+ },
2848
+ setSessionStorage: (name, value) => sessionStorage.setItem(name, value),
2849
+ setLocaleStorage: (name, value) => localStorage.setItem(name, value)
2850
+ };
2851
+ const getDefaultsOptions = () => {
2852
+ return {
2853
+ order: [
2854
+ LanguageDetector.Querystring,
2855
+ LanguageDetector.Storage,
2856
+ LanguageDetector.Navigator,
2857
+ LanguageDetector.HtmlTag
2858
+ ],
2859
+ lookupQuerystring: "locale",
2860
+ htmlTag: typeof document !== "undefined" ? document.documentElement : null
2861
+ };
2862
+ };
2863
+ const detectLanguage = (order, options) => {
2864
+ const detected = {};
2865
+ const queryStringDetector = () => {
2866
+ if (typeof window === "undefined") return;
2867
+ const search = window.location.search || "";
2868
+ const value = new URLSearchParams(search).get(options.lookupQuerystring ?? "");
2869
+ if (value) detected[LanguageDetector.Querystring] = value;
2870
+ };
2871
+ const storageDetector = () => {
2872
+ if (typeof window === "undefined") return;
2873
+ const locale = getLocaleFromStorage({
2874
+ getCookie: (name) => {
2875
+ try {
2876
+ const cookies = document.cookie.split(";");
2877
+ const cookieName = `${name}=`;
2878
+ const cookie = cookies.find((c) => c.trim().startsWith(cookieName));
2879
+ if (cookie) return cookie.split("=")[1].trim();
2880
+ } catch {}
2881
+ },
2882
+ getSessionStorage: (name) => {
2883
+ try {
2884
+ return window.sessionStorage.getItem(name) ?? void 0;
2885
+ } catch {}
2886
+ },
2887
+ getLocaleStorage: (name) => {
2888
+ try {
2889
+ return window.localStorage.getItem(name) ?? void 0;
2890
+ } catch {}
2891
+ }
2892
+ });
2893
+ if (locale) detected[LanguageDetector.Storage] = locale;
2894
+ };
2895
+ const navigatorDetector = () => {
2896
+ if (typeof navigator === "undefined") return;
2897
+ const { internationalization } = configuration;
2898
+ const languages = navigator.languages ?? [navigator.language];
2899
+ const locale = localeDetector({ "accept-language": languages.join(",") }, internationalization.locales, internationalization.defaultLocale);
2900
+ if (locale) detected[LanguageDetector.Navigator] = locale;
2901
+ };
2902
+ const htmlTagDetector = () => {
2903
+ const htmlTag = options.htmlTag;
2904
+ if (htmlTag && typeof htmlTag.getAttribute === "function") {
2905
+ const lang = htmlTag.getAttribute("lang");
2906
+ if (lang) {
2907
+ const { internationalization } = configuration;
2908
+ const locale = localeDetector({ "accept-language": lang }, internationalization.locales, internationalization.defaultLocale);
2909
+ detected[LanguageDetector.HtmlTag] = locale;
2910
+ }
2911
+ }
2912
+ };
2913
+ const detectors = {
2914
+ [LanguageDetector.Querystring]: queryStringDetector,
2915
+ [LanguageDetector.Storage]: storageDetector,
2916
+ [LanguageDetector.Navigator]: navigatorDetector,
2917
+ [LanguageDetector.HtmlTag]: htmlTagDetector
2918
+ };
2919
+ order.forEach((detectorName) => {
2920
+ var _detectors$detectorNa;
2921
+ (_detectors$detectorNa = detectors[detectorName]) === null || _detectors$detectorNa === void 0 || _detectors$detectorNa.call(detectors);
2922
+ });
2923
+ return detected;
2924
+ };
2925
+ const getFirstAvailableLocale = (locales, order) => {
2926
+ const { internationalization } = configuration;
2927
+ for (const detector of order) {
2928
+ const locale = locales[detector];
2929
+ if (locale && internationalization.locales.includes(locale)) return locale;
2930
+ }
2931
+ return (internationalization === null || internationalization === void 0 ? void 0 : internationalization.defaultLocale) ?? Locales.ENGLISH;
2932
+ };
2933
+ /**
2934
+ * Core language detector function for browser environments.
2935
+ *
2936
+ * Detects the user's preferred locale by checking multiple sources in order:
2937
+ * 1. Query string parameter
2938
+ * 2. Storage (cookies, localStorage, sessionStorage) - uses getLocaleFromStorage
2939
+ * 3. Navigator languages - uses localeDetector
2940
+ * 4. HTML lang attribute - uses localeDetector
2941
+ *
2942
+ * @param userOptions - Optional configuration for detection order and lookup keys
2943
+ * @returns The detected locale or the default locale
2944
+ *
2945
+ * @example
2946
+ * const locale = getBrowserLocale({ order: [LanguageDetector.Storage, LanguageDetector.Navigator] });
2947
+ */
2948
+ const getBrowserLocale = (userOptions = {}) => {
2949
+ const options = {
2950
+ ...getDefaultsOptions(),
2951
+ ...userOptions
2952
+ };
2953
+ return getFirstAvailableLocale(detectLanguage(options.order ?? [], options), options.order ?? []);
2954
+ };
2955
+
2956
+ //#endregion
2957
+ //#region src/localization/getHTMLTextDir.ts
2958
+ /**
2959
+ * Returns the text direction of the given locale.
2960
+ *
2961
+ * Example:
2962
+ *
2963
+ * getHTMLTextDir('en-US') // 'ltr'
2964
+ * getHTMLTextDir('en') // 'ltr'
2965
+ * getHTMLTextDir('fr-CA') // 'ltr'
2966
+ * getHTMLTextDir('fr') // 'ltr'
2967
+ *
2968
+ * @param locale The locale to get the text direction for.
2969
+ * @returns The text direction of the given locale.
2970
+ */
2971
+ const getHTMLTextDir = (locale) => {
2972
+ switch (locale) {
2973
+ case Locales.ARABIC:
2974
+ case Locales.FARSI:
2975
+ case Locales.URDU:
2976
+ case Locales.PASHTO:
2977
+ case Locales.SYRIAC:
2978
+ case Locales.ARABIC_UNITED_ARAB_EMIRATES:
2979
+ case Locales.ARABIC_BAHRAIN:
2980
+ case Locales.ARABIC_ALGERIA:
2981
+ case Locales.ARABIC_EGYPT:
2982
+ case Locales.ARABIC_IRAQ:
2983
+ case Locales.ARABIC_JORDAN:
2984
+ case Locales.ARABIC_KUWAIT:
2985
+ case Locales.ARABIC_LEBANON:
2986
+ case Locales.ARABIC_LIBYA:
2987
+ case Locales.ARABIC_MOROCCO:
2988
+ case Locales.ARABIC_OMAN:
2989
+ case Locales.ARABIC_QATAR:
2990
+ case Locales.ARABIC_SAUDI_ARABIA:
2991
+ case Locales.ARABIC_SYRIA:
2992
+ case Locales.ARABIC_TUNISIA:
2993
+ case Locales.ARABIC_YEMEN:
2994
+ case Locales.FARSI_IRAN:
2995
+ case Locales.URDU_ISLAMIC_REPUBLIC_OF_PAKISTAN:
2996
+ case Locales.PASHTO_AFGHANISTAN:
2997
+ case Locales.SYRIAC_SYRIA: return "rtl";
2998
+ default: return "ltr";
2999
+ }
3000
+ };
3001
+
3002
+ //#endregion
3003
+ //#region src/utils/checkIsURLAbsolute.ts
3004
+ const checkIsURLAbsolute = (url) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(url);
3005
+
3006
+ //#endregion
3007
+ //#region src/localization/getLocaleFromPath.ts
3008
+ /**
3009
+ * Extracts the locale segment from the given URL or pathname if present.
3010
+ * If no locale is present, returns the default locale (en).
3011
+ *
3012
+ * Example:
3013
+ *
3014
+ * ```ts
3015
+ * getLocaleFromPath('/en/dashboard') // Returns 'en'
3016
+ * getLocaleFromPath('/fr/dashboard') // Returns 'fr'
3017
+ * getLocaleFromPath('/dashboard') // Returns 'en'
3018
+ * getLocaleFromPath('dashboard') // Returns 'en'
3019
+ * getLocaleFromPath('https://example.com/es/dashboard') // Returns 'es'
3020
+ * getLocaleFromPath('https://example.com/fr/dashboard') // Returns 'fr'
3021
+ * getLocaleFromPath('https://example.com/dashboard') // Returns 'en'
3022
+ * ```
3023
+ *
3024
+ * @param inputUrl - The complete URL string or pathname to process.
3025
+ * @returns The detected locale or default (en) if no locale is found
3026
+ */
3027
+ const getLocaleFromPath = (inputUrl) => {
3028
+ const { defaultLocale, locales } = (configuration === null || configuration === void 0 ? void 0 : configuration.internationalization) ?? {};
3029
+ if (!defaultLocale || !locales) return Locales.ENGLISH;
3030
+ const isAbsoluteUrl = checkIsURLAbsolute(inputUrl);
3031
+ let fixedInputUrl = inputUrl;
3032
+ if (inputUrl.endsWith("/")) fixedInputUrl = inputUrl.slice(0, -1);
3033
+ const pathname = (isAbsoluteUrl ? new URL(fixedInputUrl) : new URL(fixedInputUrl, "http://example.com")).pathname;
3034
+ if (!pathname.startsWith("/")) return defaultLocale;
3035
+ const firstSegment = pathname.split("/")[1];
3036
+ if (firstSegment && locales.includes(firstSegment)) return firstSegment;
3037
+ return defaultLocale;
3038
+ };
3039
+
3040
+ //#endregion
3041
+ //#region src/localization/getLocaleLang.ts
3042
+ /**
3043
+ * Returns the language code of the given locale for locales including the country code.
3044
+ *
3045
+ * Example:
3046
+ *
3047
+ * getLocaleLang('en-US') // 'en'
3048
+ * getLocaleLang('en') // 'en'
3049
+ * getLocaleLang('fr-CA') // 'fr'
3050
+ * getLocaleLang('fr') // 'fr'
3051
+ *
3052
+ * @param locale The locale to get the language code for.
3053
+ * @returns The language code of the given locale.
3054
+ */
3055
+ const getLocaleLang = (locale) => (locale === null || locale === void 0 ? void 0 : locale.split("-")[0]) ?? "";
3056
+
3057
+ //#endregion
3058
+ //#region src/localization/getLocaleName.ts
3059
+ const getLocaleName = (displayLocale, targetLocale = displayLocale) => {
3060
+ return new CachedIntl.DisplayNames(targetLocale, { type: "language" }).of(displayLocale) ?? "Unknown locale";
3061
+ };
3062
+
3063
+ //#endregion
3064
+ //#region src/localization/getPathWithoutLocale.ts
3065
+ /**
3066
+ * Removes the locale segment from the given URL or pathname if present.
3067
+ * Also removes locale from search parameters if present.
3068
+ *
3069
+ * This function get the locales from the configuration if not provided.
3070
+ *
3071
+ * Example:
3072
+ *
3073
+ * ```ts
3074
+ * getPathWithoutLocale('/en/dashboard') // Returns '/dashboard'
3075
+ * getPathWithoutLocale('/fr/dashboard') // Returns '/dashboard'
3076
+ * getPathWithoutLocale('/dashboard') // Returns '/dashboard'
3077
+ * getPathWithoutLocale('dashboard') // Returns 'dashboard'
3078
+ * getPathWithoutLocale('/dashboard?locale=fr') // Returns '/dashboard'
3079
+ * getPathWithoutLocale('https://example.com/en/dashboard') // Returns 'https://example.com/dashboard'
3080
+ * getPathWithoutLocale('https://example.com/fr/dashboard') // Returns 'https://example.com/dashboard'
3081
+ * getPathWithoutLocale('https://example.com/dashboard') // Returns 'https://example.com/dashboard'
3082
+ * getPathWithoutLocale('https://example.com/dashboard?locale=fr') // Returns 'https://example.com/dashboard'
3083
+ * ```
3084
+ *
3085
+ * @param inputUrl - The complete URL string or pathname to process.
3086
+ * @param locales - Optional array of supported locales. Defaults to `localesDefault`.
3087
+ * @returns The URL string or pathname without the locale segment or locale search parameter.
3088
+ */
3089
+ const getPathWithoutLocale = (inputUrl, locales = (() => {
3090
+ var _configuration$intern;
3091
+ return configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.locales;
3092
+ })()) => {
3093
+ const isAbsoluteUrl = checkIsURLAbsolute(inputUrl);
3094
+ let fixedInputUrl = inputUrl;
3095
+ if (inputUrl.endsWith("/")) fixedInputUrl = inputUrl.slice(0, -1);
3096
+ const url = isAbsoluteUrl ? new URL(fixedInputUrl) : new URL(fixedInputUrl, "http://example.com");
3097
+ const pathname = url.pathname;
3098
+ if (!pathname.startsWith("/")) url.pathname = `/${pathname}`;
3099
+ const pathSegments = pathname.split("/");
3100
+ const firstSegment = pathSegments[1];
3101
+ if (locales === null || locales === void 0 ? void 0 : locales.includes(firstSegment)) {
3102
+ pathSegments.splice(1, 1);
3103
+ url.pathname = pathSegments.join("/") ?? "/";
3104
+ }
3105
+ const searchParams = new URLSearchParams(url.search);
3106
+ if (searchParams.has("locale")) {
3107
+ searchParams.delete("locale");
3108
+ url.search = searchParams.toString();
3109
+ }
3110
+ if (isAbsoluteUrl) return url.toString();
3111
+ return url.toString().replace("http://example.com", "");
3112
+ };
3113
+
3114
+ //#endregion
3115
+ //#region src/localization/getMultilingualUrls.ts
3116
+ var _configuration$intern2$1, _configuration$routin$2;
3117
+ /**
3118
+ * Generates multilingual URLs by prefixing the given URL with each supported locale
3119
+ * or adding search parameters based on the routing mode.
3120
+ * Handles both absolute and relative URLs appropriately.
3121
+ *
3122
+ * This function gets the locales, default locale, and routing mode from the configuration if not provided.
3123
+ *
3124
+ * Example:
3125
+ *
3126
+ * ```ts
3127
+ * // prefix-no-default mode
3128
+ * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'prefix-no-default')
3129
+ * // Returns { en: '/dashboard', fr: '/fr/dashboard' }
3130
+ *
3131
+ * // prefix-all mode
3132
+ * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'prefix-all')
3133
+ * // Returns { en: '/en/dashboard', fr: '/fr/dashboard' }
3134
+ *
3135
+ * // search-params mode
3136
+ * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'search-params')
3137
+ * // Returns { en: '/dashboard?locale=en', fr: '/dashboard?locale=fr' }
3138
+ *
3139
+ * // no-prefix mode
3140
+ * getMultilingualUrls('/dashboard', ['en', 'fr'], 'en', 'no-prefix')
3141
+ * // Returns { en: '/dashboard', fr: '/dashboard' }
3142
+ * ```
3143
+ *
3144
+ * @param url - The original URL string to be processed.
3145
+ * @param locales - Optional array of supported locales. Defaults to configured locales.
3146
+ * @param defaultLocale - The default locale. Defaults to configured default locale.
3147
+ * @param mode - URL routing mode for locale handling. Defaults to configured mode.
3148
+ * @returns An object mapping each locale to its corresponding multilingual URL.
3149
+ */
3150
+ const getMultilingualUrls = (url, locales = (() => {
3151
+ var _configuration$intern;
3152
+ return configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.locales;
3153
+ })(), defaultLocale = configuration === null || configuration === void 0 || (_configuration$intern2$1 = configuration.internationalization) === null || _configuration$intern2$1 === void 0 ? void 0 : _configuration$intern2$1.defaultLocale, mode = configuration === null || configuration === void 0 || (_configuration$routin$2 = configuration.routing) === null || _configuration$routin$2 === void 0 ? void 0 : _configuration$routin$2.mode) => {
3154
+ const urlWithoutLocale = getPathWithoutLocale(url, locales);
3155
+ const isAbsoluteUrl = checkIsURLAbsolute(urlWithoutLocale);
3156
+ const parsedUrl = isAbsoluteUrl ? new URL(urlWithoutLocale) : new URL(urlWithoutLocale, "http://example.com");
3157
+ let pathname = parsedUrl.pathname;
3158
+ if (!pathname.startsWith("/")) pathname = `/${pathname}`;
3159
+ const baseUrl = isAbsoluteUrl ? `${parsedUrl.protocol}//${parsedUrl.host}` : "";
3160
+ const routingMode = mode ?? DefaultValues.Routing.ROUTING_MODE;
3161
+ return (locales ?? []).reduce((acc, locale) => {
3162
+ const isDefaultLocale = (locale === null || locale === void 0 ? void 0 : locale.toString()) === (defaultLocale === null || defaultLocale === void 0 ? void 0 : defaultLocale.toString());
3163
+ let localizedUrl;
3164
+ if (routingMode === "search-params") {
3165
+ const searchParams = new URLSearchParams(parsedUrl.search);
3166
+ searchParams.set("locale", locale.toString());
3167
+ const queryString = searchParams.toString();
3168
+ const pathWithQuery = queryString ? `${pathname}?${queryString}` : pathname;
3169
+ localizedUrl = isAbsoluteUrl ? `${baseUrl}${pathWithQuery}${parsedUrl.hash}` : `${pathWithQuery}${parsedUrl.hash}`;
3170
+ } else if (routingMode === "no-prefix") localizedUrl = isAbsoluteUrl ? `${baseUrl}${pathname}${parsedUrl.search}${parsedUrl.hash}` : `${pathname}${parsedUrl.search}${parsedUrl.hash}`;
3171
+ else {
3172
+ let localizedPath = routingMode === "prefix-all" || routingMode === "prefix-no-default" && !isDefaultLocale ? `/${locale}${pathname}` : pathname;
3173
+ if (localizedPath.length > 1 && localizedPath.endsWith("/")) localizedPath = localizedPath.slice(0, -1);
3174
+ localizedUrl = isAbsoluteUrl ? `${baseUrl}${localizedPath}${parsedUrl.search}${parsedUrl.hash}` : `${localizedPath}${parsedUrl.search}${parsedUrl.hash}`;
3175
+ }
3176
+ acc[locale] = localizedUrl;
3177
+ return acc;
3178
+ }, {});
3179
+ };
3180
+
3181
+ //#endregion
3182
+ //#region src/localization/getLocalizedUrl.ts
3183
+ var _configuration$intern2, _configuration$routin$1;
3184
+ /**
3185
+ * Generate URL by prefixing the given URL with the referenced locale or adding search parameters
3186
+ * based on the routing mode. Handles both absolute and relative URLs appropriately.
3187
+ *
3188
+ * This function gets the locales, default locale, and routing mode from the configuration if not provided.
3189
+ *
3190
+ * Example:
3191
+ *
3192
+ * ```ts
3193
+ * // prefix-no-default mode
3194
+ * getLocalizedUrl('/about', 'fr', ['en', 'fr'], 'en', 'prefix-no-default');
3195
+ * // Returns '/fr/about' for the French locale
3196
+ * // Returns '/about' for the English locale (default)
3197
+ *
3198
+ * // prefix-all mode
3199
+ * getLocalizedUrl('/about', 'en', ['en', 'fr'], 'en', 'prefix-all');
3200
+ * // Returns '/en/about' for the English locale
3201
+ * // Returns '/fr/about' for the French locale
3202
+ *
3203
+ * // search-params mode
3204
+ * getLocalizedUrl('/about', 'fr', ['en', 'fr'], 'en', 'search-params');
3205
+ * // Returns '/about?locale=fr' for the French locale
3206
+ *
3207
+ * // no-prefix mode
3208
+ * getLocalizedUrl('/about', 'fr', ['en', 'fr'], 'en', 'no-prefix');
3209
+ * // Returns '/about' for any locale
3210
+ * ```
3211
+ *
3212
+ * @param url - The original URL string to be processed.
3213
+ * @param currentLocale - The current locale.
3214
+ * @param locales - Optional array of supported locales. Defaults to configured locales.
3215
+ * @param defaultLocale - The default locale. Defaults to configured default locale.
3216
+ * @param mode - URL routing mode for locale handling. Defaults to configured mode.
3217
+ * @returns The localized URL for the current locale.
3218
+ */
3219
+ const getLocalizedUrl = (url, currentLocale, locales = (() => {
3220
+ var _configuration$intern;
3221
+ return configuration === null || configuration === void 0 || (_configuration$intern = configuration.internationalization) === null || _configuration$intern === void 0 ? void 0 : _configuration$intern.locales;
3222
+ })(), defaultLocale = configuration === null || configuration === void 0 || (_configuration$intern2 = configuration.internationalization) === null || _configuration$intern2 === void 0 ? void 0 : _configuration$intern2.defaultLocale, mode = configuration === null || configuration === void 0 || (_configuration$routin$1 = configuration.routing) === null || _configuration$routin$1 === void 0 ? void 0 : _configuration$routin$1.mode) => {
3223
+ return getMultilingualUrls(url, locales, defaultLocale, mode)[currentLocale] ?? url;
3224
+ };
3225
+
3226
+ //#endregion
3227
+ //#region src/localization/localeMapper.ts
3228
+ var _configuration$routin, _configuration$routin2, _configuration$routin3;
3229
+ /**
3230
+ * Determine if the locale should be prefixed in the URL based on routing mode
3231
+ */
3232
+ const shouldPrefixLocale = (locale, defaultLocale, mode) => {
3233
+ if (mode === "no-prefix" || mode === "search-params") return false;
3234
+ if (mode === "prefix-all") return true;
3235
+ return locale !== defaultLocale;
3236
+ };
3237
+ /**
3238
+ * Map the locale data to an array of objects
3239
+ *
3240
+ * @example
3241
+ * ```ts
3242
+ * const routes = localeMap((localizedData) =>
3243
+ * ({
3244
+ * path: localizedData.urlPrefix,
3245
+ * name: localizedData.locale,
3246
+ * isDefault: localizedData.isDefault,
3247
+ * locales: localizedData.locales,
3248
+ * defaultLocale: localizedData.defaultLocale,
3249
+ * }),
3250
+ * );
3251
+ *
3252
+ * // Result
3253
+ * [
3254
+ * { path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' },
3255
+ * { path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' },
3256
+ * { path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' },
3257
+ * ]
3258
+ * ```
3259
+ *
3260
+ * @param mapper - The mapper function that returns an object
3261
+ * @returns An array of objects
3262
+ */
3263
+ const localeMap = (mapper, locales = (() => {
3264
+ return configuration === null || configuration === void 0 ? void 0 : configuration.internationalization.locales;
3265
+ })() ?? [], defaultLocale = (configuration === null || configuration === void 0 ? void 0 : configuration.internationalization.defaultLocale) ?? Locales.ENGLISH, mode = (configuration === null || configuration === void 0 || (_configuration$routin = configuration.routing) === null || _configuration$routin === void 0 ? void 0 : _configuration$routin.mode) ?? "prefix-no-default") => (locales ?? []).map((locale) => mapper({
3266
+ locale,
3267
+ defaultLocale,
3268
+ locales,
3269
+ isDefault: locale === defaultLocale,
3270
+ urlPrefix: shouldPrefixLocale(locale, defaultLocale, mode) ? `/${locale}` : ""
3271
+ }));
3272
+ /**
3273
+ * Flatten the locale map into a single array of objects
3274
+ *
3275
+ * @example
3276
+ * ```ts
3277
+ * const routes = localeMap((localizedData) =>
3278
+ * [{
3279
+ * path: localizedData.urlPrefix,
3280
+ * name: localizedData.locale,
3281
+ * isDefault: localizedData.isDefault,
3282
+ * locales: localizedData.locales,
3283
+ * defaultLocale: localizedData.defaultLocale,
3284
+ * }],
3285
+ * );
3286
+ *
3287
+ * // Result
3288
+ * [
3289
+ * path: '/', name: 'en', isDefault: true, locales: ['en'], defaultLocale: 'en', urlPrefix: '' ,
3290
+ * path: '/fr', name: 'fr', isDefault: false, locales: ['fr'], defaultLocale: 'en', urlPrefix: '/fr' ,
3291
+ * path: '/es', name: 'es', isDefault: false, locales: ['es'], defaultLocale: 'en', urlPrefix: '/es' ,
3292
+ * ]
3293
+ * ```
3294
+ *
3295
+ * @param mapper - The mapper function that returns an array of objects
3296
+ * @returns An array of objects
3297
+ */
3298
+ const localeFlatMap = (mapper, locales = (() => {
3299
+ return configuration === null || configuration === void 0 ? void 0 : configuration.internationalization.locales;
3300
+ })() ?? [], defaultLocale = (configuration === null || configuration === void 0 ? void 0 : configuration.internationalization.defaultLocale) ?? Locales.ENGLISH, mode = (configuration === null || configuration === void 0 || (_configuration$routin2 = configuration.routing) === null || _configuration$routin2 === void 0 ? void 0 : _configuration$routin2.mode) ?? "prefix-no-default") => locales.flatMap((locale) => mapper({
3301
+ locale,
3302
+ defaultLocale,
3303
+ locales,
3304
+ isDefault: locale === defaultLocale,
3305
+ urlPrefix: shouldPrefixLocale(locale, defaultLocale, mode) ? `/${locale}` : ""
3306
+ }));
3307
+ /**
3308
+ * Creates a record object mapping locales to values transformed by the mapper function
3309
+ *
3310
+ * @example
3311
+ * ```ts
3312
+ * const translations = localeRecord(({ locale }) =>
3313
+ * require(`./translations/${locale}.json`)
3314
+ * );
3315
+ *
3316
+ * // Result
3317
+ *
3318
+ * en: ... , // Content of translations/en.json
3319
+ * fr: ... , // Content of translations/fr.json
3320
+ * es: ...
3321
+ *
3322
+ * ```
3323
+ *
3324
+ * @param mapper - Function that takes locale data and returns a value for that locale
3325
+ * @param locales - Array of locale codes to map over (defaults to configured locales)
3326
+ * @param defaultLocale - The default locale (defaults to configured default)
3327
+ * @param mode - URL routing mode for locale handling (defaults to configured value)
3328
+ * @returns Record mapping locale codes to mapped values
3329
+ */
3330
+ const localeRecord = (mapper, locales = (() => {
3331
+ return configuration === null || configuration === void 0 ? void 0 : configuration.internationalization.locales;
3332
+ })() ?? [], defaultLocale = (configuration === null || configuration === void 0 ? void 0 : configuration.internationalization.defaultLocale) ?? Locales.ENGLISH, mode = (configuration === null || configuration === void 0 || (_configuration$routin3 = configuration.routing) === null || _configuration$routin3 === void 0 ? void 0 : _configuration$routin3.mode) ?? "prefix-no-default") => (locales ?? []).reduce((acc, locale) => {
3333
+ acc[locale] = mapper({
3334
+ locale,
3335
+ defaultLocale,
3336
+ locales,
3337
+ isDefault: locale === defaultLocale,
3338
+ urlPrefix: shouldPrefixLocale(locale, defaultLocale, mode) ? `/${locale}` : ""
3339
+ });
3340
+ return acc;
3341
+ }, {});
3342
+
3343
+ //#endregion
3344
+ //#region src/utils/isSameKeyPath.ts
3345
+ const isSameKeyPath = (keyPath1, keyPath2) => keyPath1.every((element, index) => keyPath2[index] && keyPath2[index].key === element.key && keyPath2[index].type === element.type);
3346
+
3347
+ //#endregion
3348
+ export { CachedIntl, CachedIntl as Intl, LocaleStorage, buildMaskPlugin, checkIsURLAbsolute, checkMissingLocalesPlugin, compact, condition as cond, conditionPlugin, createCachedIntl, currency, date, deepTransformNode, editDictionaryByKeyPath, enumeration as enu, enumerationPlugin, filePlugin, filterMissingTranslationsOnlyPlugin, filterTranslationsOnlyPlugin, findMatchingCondition, gender, genderPlugin, getBrowserLocale, getCondition, getContent, getContentNodeByKeyPath, getDefaultNode, getDictionary, getEmptyNode, getEnumeration, getFilterMissingTranslationsContent, getFilterMissingTranslationsDictionary, getFilterTranslationsOnlyContent, getFilterTranslationsOnlyDictionary, getFilteredLocalesContent, getFilteredLocalesDictionary, getHTMLTextDir, getInsertionValues, getIntlayer, getLocaleFromPath, getLocaleFromStorage, getLocaleLang, getLocaleName, getLocalizedContent, getLocalizedUrl, getMarkdownMetadata, getMaskContent, getMissingLocalesContent, getMissingLocalesContentFromDictionary, getMultilingualDictionary, getMultilingualUrls, getNesting, getNodeChildren, getNodeType, getPathWithoutLocale, getPerLocaleDictionary, getReplacedValuesContent, getSplittedContent, getSplittedDictionaryContent, getStorageAttributes, getTranslation, insertion as insert, insertContentInDictionary, insertionPlugin, isSameKeyPath, isValidElement, list, localeDetector, localeFlatMap, localeMap, localeRecord, localeResolver, localeStorageOptions, markdown as md, mergeDictionaries, nesting as nest, nestedPlugin, normalizeDictionaries, normalizeDictionary, number, orderDictionaries, parseYaml, percentage, relativeTime, removeContentNodeByKeyPath, renameContentNodeByKeyPath, setLocaleInStorage, translation as t, translationPlugin, units, updateNodeChildren };