@intlayer/core 9.4.1 → 9.4.3

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 (220) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/index.cjs +8 -4
  3. package/dist/cjs/localization/getCanonicalPath.cjs +52 -0
  4. package/dist/cjs/localization/getCanonicalPath.cjs.map +1 -0
  5. package/dist/cjs/localization/getCanonicalPath.test-d.cjs +12 -0
  6. package/dist/cjs/localization/getCanonicalPath.test-d.cjs.map +1 -0
  7. package/dist/cjs/localization/getLocalizedPath.cjs +4 -2
  8. package/dist/cjs/localization/getLocalizedPath.cjs.map +1 -1
  9. package/dist/cjs/localization/index.cjs +4 -2
  10. package/dist/cjs/localization/rewriteMatch.cjs +52 -0
  11. package/dist/cjs/localization/rewriteMatch.cjs.map +1 -0
  12. package/dist/cjs/localization/rewriteUtils.cjs +6 -68
  13. package/dist/cjs/localization/rewriteUtils.cjs.map +1 -1
  14. package/dist/cjs/localization/rewriteUtils.test-d.cjs +0 -5
  15. package/dist/cjs/localization/rewriteUtils.test-d.cjs.map +1 -1
  16. package/dist/cjs/markdown/compiler.cjs +100 -75
  17. package/dist/cjs/markdown/compiler.cjs.map +1 -1
  18. package/dist/cjs/markdown/constants.cjs +14 -5
  19. package/dist/cjs/markdown/constants.cjs.map +1 -1
  20. package/dist/cjs/markdown/index.cjs +4 -2
  21. package/dist/cjs/markdown/parser.cjs +70 -44
  22. package/dist/cjs/markdown/parser.cjs.map +1 -1
  23. package/dist/cjs/markdown/renderer.cjs +7 -19
  24. package/dist/cjs/markdown/renderer.cjs.map +1 -1
  25. package/dist/cjs/markdown/utils.cjs +33 -37
  26. package/dist/cjs/markdown/utils.cjs.map +1 -1
  27. package/dist/esm/index.mjs +5 -3
  28. package/dist/esm/localization/getCanonicalPath.mjs +51 -0
  29. package/dist/esm/localization/getCanonicalPath.mjs.map +1 -0
  30. package/dist/esm/localization/getCanonicalPath.test-d.mjs +12 -0
  31. package/dist/esm/localization/getCanonicalPath.test-d.mjs.map +1 -0
  32. package/dist/esm/localization/getLocalizedPath.mjs +3 -1
  33. package/dist/esm/localization/getLocalizedPath.mjs.map +1 -1
  34. package/dist/esm/localization/index.mjs +3 -1
  35. package/dist/esm/localization/rewriteMatch.mjs +49 -0
  36. package/dist/esm/localization/rewriteMatch.mjs.map +1 -0
  37. package/dist/esm/localization/rewriteUtils.mjs +3 -63
  38. package/dist/esm/localization/rewriteUtils.mjs.map +1 -1
  39. package/dist/esm/localization/rewriteUtils.test-d.mjs +1 -6
  40. package/dist/esm/localization/rewriteUtils.test-d.mjs.map +1 -1
  41. package/dist/esm/markdown/compiler.mjs +101 -55
  42. package/dist/esm/markdown/compiler.mjs.map +1 -1
  43. package/dist/esm/markdown/constants.mjs +11 -4
  44. package/dist/esm/markdown/constants.mjs.map +1 -1
  45. package/dist/esm/markdown/index.mjs +2 -2
  46. package/dist/esm/markdown/parser.mjs +70 -44
  47. package/dist/esm/markdown/parser.mjs.map +1 -1
  48. package/dist/esm/markdown/renderer.mjs +7 -19
  49. package/dist/esm/markdown/renderer.mjs.map +1 -1
  50. package/dist/esm/markdown/utils.mjs +34 -38
  51. package/dist/esm/markdown/utils.mjs.map +1 -1
  52. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
  53. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
  54. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  55. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
  56. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
  57. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  58. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
  59. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
  60. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
  61. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
  62. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
  63. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
  64. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
  65. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
  66. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  67. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
  68. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
  69. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  70. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
  71. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
  72. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
  73. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
  74. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
  75. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
  76. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
  77. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
  78. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
  79. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  80. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
  81. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
  82. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  83. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
  84. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
  85. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
  86. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
  87. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
  88. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
  89. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
  90. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
  91. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
  92. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  93. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
  94. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
  95. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  96. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
  97. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
  98. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
  99. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
  100. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
  101. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
  102. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
  103. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +1 -0
  104. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +1 -0
  105. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +1 -0
  106. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +1 -0
  107. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +1 -0
  108. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +1 -0
  109. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +1 -0
  110. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +7 -0
  111. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +1 -0
  112. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
  113. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +2 -0
  114. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
  115. package/dist/types/@intlayer/core/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +1 -0
  116. package/dist/types/@intlayer/core/dist/types/dictionaryManipulator/plainDynamicLoader.d.ts +2 -0
  117. package/dist/types/@intlayer/core/dist/types/dictionaryManipulator/qualifiedDynamicLoader.d.ts +2 -0
  118. package/dist/types/@intlayer/core/dist/types/formatters/compact.d.ts +1 -0
  119. package/dist/types/@intlayer/core/dist/types/formatters/currency.d.ts +1 -0
  120. package/dist/types/@intlayer/core/dist/types/formatters/date.d.ts +1 -0
  121. package/dist/types/@intlayer/core/dist/types/formatters/index.d.ts +9 -0
  122. package/dist/types/@intlayer/core/dist/types/formatters/list.d.ts +1 -0
  123. package/dist/types/@intlayer/core/dist/types/formatters/number.d.ts +1 -0
  124. package/dist/types/@intlayer/core/dist/types/formatters/percentage.d.ts +1 -0
  125. package/dist/types/@intlayer/core/dist/types/formatters/relativeTime.d.ts +1 -0
  126. package/dist/types/@intlayer/core/dist/types/formatters/units.d.ts +1 -0
  127. package/dist/types/@intlayer/core/dist/types/interpreter/dictionaryTransformCache.d.ts +4 -0
  128. package/dist/types/@intlayer/core/dist/types/interpreter/getCondition.d.ts +2 -0
  129. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/deepTransform.d.ts +1 -0
  130. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/getContent.d.ts +3 -0
  131. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/index.d.ts +3 -0
  132. package/dist/types/@intlayer/core/dist/types/interpreter/getContent/plugins.d.ts +7 -0
  133. package/dist/types/@intlayer/core/dist/types/interpreter/getDictionary.d.ts +4 -0
  134. package/dist/types/@intlayer/core/dist/types/interpreter/getDictionaryAsync.d.ts +6 -0
  135. package/dist/types/@intlayer/core/dist/types/interpreter/getEnumeration.d.ts +2 -0
  136. package/dist/types/@intlayer/core/dist/types/interpreter/getGender.d.ts +2 -0
  137. package/dist/types/@intlayer/core/dist/types/interpreter/getInsertion.d.ts +2 -0
  138. package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayer.d.ts +4 -0
  139. package/dist/types/@intlayer/core/dist/types/interpreter/getIntlayerAsync.d.ts +4 -0
  140. package/dist/types/@intlayer/core/dist/types/interpreter/getNesting.d.ts +6 -0
  141. package/dist/types/@intlayer/core/dist/types/interpreter/getPlural.d.ts +3 -0
  142. package/dist/types/@intlayer/core/dist/types/interpreter/getSelect.d.ts +2 -0
  143. package/dist/types/@intlayer/core/dist/types/interpreter/getTranslation.d.ts +1 -0
  144. package/dist/types/@intlayer/core/dist/types/interpreter/index.d.ts +18 -0
  145. package/dist/types/@intlayer/core/dist/types/interpreter/interpolableNode.d.ts +2 -0
  146. package/dist/types/@intlayer/core/dist/types/intlayer/dist/types/index.d.ts +6 -0
  147. package/dist/types/@intlayer/core/dist/types/localization/comparePaths.d.ts +1 -0
  148. package/dist/types/@intlayer/core/dist/types/localization/domainUtils.d.ts +2 -0
  149. package/dist/types/@intlayer/core/dist/types/localization/generateSitemap.d.ts +2 -0
  150. package/dist/types/@intlayer/core/dist/types/localization/getBrowserLocale.d.ts +1 -0
  151. package/dist/types/@intlayer/core/dist/types/localization/getCanonicalPath.d.ts +2 -0
  152. package/dist/types/@intlayer/core/dist/types/localization/getHTMLTextDir.d.ts +1 -0
  153. package/dist/types/@intlayer/core/dist/types/localization/getLocale.d.ts +1 -0
  154. package/dist/types/@intlayer/core/dist/types/localization/getLocaleFromPath.d.ts +2 -0
  155. package/dist/types/@intlayer/core/dist/types/localization/getLocaleLang.d.ts +1 -0
  156. package/dist/types/@intlayer/core/dist/types/localization/getLocaleName.d.ts +1 -0
  157. package/dist/types/@intlayer/core/dist/types/localization/getLocalizedPath.d.ts +2 -0
  158. package/dist/types/@intlayer/core/dist/types/localization/getLocalizedUrl.d.ts +2 -0
  159. package/dist/types/@intlayer/core/dist/types/localization/getMultilingualUrls.d.ts +2 -0
  160. package/dist/types/@intlayer/core/dist/types/localization/getPathWithoutLocale.d.ts +1 -0
  161. package/dist/types/@intlayer/core/dist/types/localization/getPrefix.d.ts +2 -0
  162. package/dist/types/@intlayer/core/dist/types/localization/index.d.ts +22 -0
  163. package/dist/types/@intlayer/core/dist/types/localization/localeDetector.d.ts +2 -0
  164. package/dist/types/@intlayer/core/dist/types/localization/localeMapper.d.ts +1 -0
  165. package/dist/types/@intlayer/core/dist/types/localization/localeResolver.d.ts +1 -0
  166. package/dist/types/@intlayer/core/dist/types/localization/resolveBrowserLocale.d.ts +2 -0
  167. package/dist/types/@intlayer/core/dist/types/localization/rewriteMatch.d.ts +1 -0
  168. package/dist/types/@intlayer/core/dist/types/localization/rewriteUtils.d.ts +2 -0
  169. package/dist/types/@intlayer/core/dist/types/localization/validatePrefix.d.ts +2 -0
  170. package/dist/types/@intlayer/core/dist/types/markdown/index.d.ts +2 -0
  171. package/dist/types/@intlayer/core/dist/types/transpiler/condition/condition.d.ts +1 -0
  172. package/dist/types/@intlayer/core/dist/types/transpiler/condition/index.d.ts +1 -0
  173. package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/enumeration.d.ts +1 -0
  174. package/dist/types/@intlayer/core/dist/types/transpiler/enumeration/index.d.ts +1 -0
  175. package/dist/types/@intlayer/core/dist/types/transpiler/file/file.d.ts +1 -0
  176. package/dist/types/@intlayer/core/dist/types/transpiler/file/index.d.ts +1 -0
  177. package/dist/types/@intlayer/core/dist/types/transpiler/gender/gender.d.ts +1 -0
  178. package/dist/types/@intlayer/core/dist/types/transpiler/gender/index.d.ts +1 -0
  179. package/dist/types/@intlayer/core/dist/types/transpiler/html/html.d.ts +1 -0
  180. package/dist/types/@intlayer/core/dist/types/transpiler/html/index.d.ts +1 -0
  181. package/dist/types/@intlayer/core/dist/types/transpiler/index.d.ts +22 -0
  182. package/dist/types/@intlayer/core/dist/types/transpiler/insertion/index.d.ts +1 -0
  183. package/dist/types/@intlayer/core/dist/types/transpiler/insertion/insertion.d.ts +1 -0
  184. package/dist/types/@intlayer/core/dist/types/transpiler/markdown/index.d.ts +1 -0
  185. package/dist/types/@intlayer/core/dist/types/transpiler/markdown/markdown.d.ts +1 -0
  186. package/dist/types/@intlayer/core/dist/types/transpiler/nesting/index.d.ts +1 -0
  187. package/dist/types/@intlayer/core/dist/types/transpiler/nesting/nesting.d.ts +4 -0
  188. package/dist/types/@intlayer/core/dist/types/transpiler/plural/index.d.ts +1 -0
  189. package/dist/types/@intlayer/core/dist/types/transpiler/plural/plural.d.ts +1 -0
  190. package/dist/types/@intlayer/core/dist/types/transpiler/select/index.d.ts +1 -0
  191. package/dist/types/@intlayer/core/dist/types/transpiler/select/select.d.ts +1 -0
  192. package/dist/types/@intlayer/core/dist/types/transpiler/translation/index.d.ts +1 -0
  193. package/dist/types/@intlayer/core/dist/types/transpiler/translation/translation.d.ts +2 -0
  194. package/dist/types/@intlayer/core/dist/types/utils/index.d.ts +3 -0
  195. package/dist/types/@intlayer/core/dist/types/utils/intl.d.ts +1 -0
  196. package/dist/types/@intlayer/core/dist/types/utils/isSameKeyPath.d.ts +1 -0
  197. package/dist/types/@intlayer/core/dist/types/utils/localeStorage.d.ts +2 -0
  198. package/dist/types/index.d.ts +5 -3
  199. package/dist/types/interpreter/getPlural.d.ts +1 -1
  200. package/dist/types/intlayer/dist/types/index.d.ts +14 -0
  201. package/dist/types/localization/getCanonicalPath.d.ts +19 -0
  202. package/dist/types/localization/getCanonicalPath.d.ts.map +1 -0
  203. package/dist/types/localization/getCanonicalPath.test-d.d.ts +1 -0
  204. package/dist/types/localization/getLocalizedPath.d.ts.map +1 -1
  205. package/dist/types/localization/index.d.ts +3 -1
  206. package/dist/types/localization/rewriteMatch.d.ts +20 -0
  207. package/dist/types/localization/rewriteMatch.d.ts.map +1 -0
  208. package/dist/types/localization/rewriteUtils.d.ts +2 -14
  209. package/dist/types/localization/rewriteUtils.d.ts.map +1 -1
  210. package/dist/types/markdown/compiler.d.ts.map +1 -1
  211. package/dist/types/markdown/constants.d.ts +11 -4
  212. package/dist/types/markdown/constants.d.ts.map +1 -1
  213. package/dist/types/markdown/index.d.ts +2 -2
  214. package/dist/types/markdown/parser.d.ts.map +1 -1
  215. package/dist/types/markdown/renderer.d.ts.map +1 -1
  216. package/dist/types/markdown/types.d.ts +8 -2
  217. package/dist/types/markdown/types.d.ts.map +1 -1
  218. package/dist/types/markdown/utils.d.ts +0 -4
  219. package/dist/types/markdown/utils.d.ts.map +1 -1
  220. package/package.json +7 -7
package/README.md CHANGED
@@ -330,4 +330,4 @@ Contribute on [GitHub](https://github.com/aymericzip/intlayer), [GitLab](https:/
330
330
 
331
331
  If you like Intlayer, give us a ⭐ on GitHub. It helps others discover the project! [See why GitHub Stars matter](https://github.com/aymericzip/intlayer/blob/main/CONTRIBUTING.md#why-github-stars-matter-).
332
332
 
333
- [![Star History Chart](https://star-history.dera.page/svg?repos=aymericzip/intlayer&type=Date)](https://star-history.dera.page/#aymericzip/intlayer&Date)
333
+ [![Star History Chart](https://api.star-history.com/svg?repos=aymericzip/intlayer&type=Date)](https://api.star-history.com/#aymericzip/intlayer&Date)
@@ -78,6 +78,8 @@ const require_utils_checkIsURLAbsolute = require('./utils/checkIsURLAbsolute.cjs
78
78
  const require_localization_getPathWithoutLocale = require('./localization/getPathWithoutLocale.cjs');
79
79
  const require_localization_comparePaths = require('./localization/comparePaths.cjs');
80
80
  const require_localization_domainUtils = require('./localization/domainUtils.cjs');
81
+ const require_localization_rewriteMatch = require('./localization/rewriteMatch.cjs');
82
+ const require_localization_getCanonicalPath = require('./localization/getCanonicalPath.cjs');
81
83
  const require_localization_getPrefix = require('./localization/getPrefix.cjs');
82
84
  const require_localization_rewriteUtils = require('./localization/rewriteUtils.cjs');
83
85
  const require_localization_getLocalizedPath = require('./localization/getLocalizedPath.cjs');
@@ -129,12 +131,12 @@ exports.CODE_INLINE_R = require_markdown_constants.CODE_INLINE_R;
129
131
  exports.COMPOSITE_ID_SEPARATOR = require_dictionaryManipulator_qualifiedDictionary.COMPOSITE_ID_SEPARATOR;
130
132
  exports.CONSECUTIVE_NEWLINE_R = require_markdown_constants.CONSECUTIVE_NEWLINE_R;
131
133
  exports.CR_NEWLINE_R = require_markdown_constants.CR_NEWLINE_R;
134
+ exports.CUSTOM_COMPONENT_OPENING_TAG_R = require_markdown_constants.CUSTOM_COMPONENT_OPENING_TAG_R;
132
135
  exports.CUSTOM_COMPONENT_R = require_markdown_constants.CUSTOM_COMPONENT_R;
133
136
  exports.CachedIntl = require_utils_intl.CachedIntl;
134
137
  exports.Intl = require_utils_intl.CachedIntl;
135
138
  exports.DEFAULT_VARIANT_ID = require_dictionaryManipulator_qualifiedDictionary.DEFAULT_VARIANT_ID;
136
139
  exports.DO_NOT_PROCESS_HTML_ELEMENTS = require_markdown_constants.DO_NOT_PROCESS_HTML_ELEMENTS;
137
- exports.DURATION_DELAY_TRIGGER = require_markdown_constants.DURATION_DELAY_TRIGGER;
138
140
  exports.FENCE_DELIMITER_R = require_markdown_constants.FENCE_DELIMITER_R;
139
141
  exports.FOOTNOTE_R = require_markdown_constants.FOOTNOTE_R;
140
142
  exports.FOOTNOTE_REFERENCE_R = require_markdown_constants.FOOTNOTE_REFERENCE_R;
@@ -145,22 +147,24 @@ exports.HEADING_ATX_COMPLIANT_R = require_markdown_constants.HEADING_ATX_COMPLIA
145
147
  exports.HEADING_R = require_markdown_constants.HEADING_R;
146
148
  exports.HEADING_SETEXT_R = require_markdown_constants.HEADING_SETEXT_R;
147
149
  exports.HTML_BLOCK_ELEMENT_R = require_markdown_constants.HTML_BLOCK_ELEMENT_R;
150
+ exports.HTML_BLOCK_OPENING_TAG_R = require_markdown_constants.HTML_BLOCK_OPENING_TAG_R;
148
151
  exports.HTML_CHAR_CODE_R = require_markdown_constants.HTML_CHAR_CODE_R;
149
152
  exports.HTML_COMMENT_R = require_markdown_constants.HTML_COMMENT_R;
150
153
  exports.HTML_CUSTOM_ATTR_R = require_markdown_constants.HTML_CUSTOM_ATTR_R;
151
154
  exports.HTML_LEFT_TRIM_AMOUNT_R = require_markdown_constants.HTML_LEFT_TRIM_AMOUNT_R;
152
155
  exports.HTML_SELF_CLOSING_ELEMENT_R = require_markdown_constants.HTML_SELF_CLOSING_ELEMENT_R;
156
+ exports.HTML_SELF_CLOSING_OPENING_TAG_R = require_markdown_constants.HTML_SELF_CLOSING_OPENING_TAG_R;
153
157
  exports.HTML_TAGS = require_transpiler_html_htmlTags.HTML_TAGS;
154
158
  exports.INLINE_SKIP_R = require_markdown_constants.INLINE_SKIP_R;
155
159
  exports.INTERPOLATION_R = require_markdown_constants.INTERPOLATION_R;
156
160
  exports.LINK_AUTOLINK_BARE_URL_R = require_markdown_constants.LINK_AUTOLINK_BARE_URL_R;
157
161
  exports.LINK_AUTOLINK_R = require_markdown_constants.LINK_AUTOLINK_R;
158
- exports.LIST_LOOKBEHIND_R = require_markdown_constants.LIST_LOOKBEHIND_R;
159
162
  exports.LOOKAHEAD = require_markdown_constants.LOOKAHEAD;
160
163
  exports.LocaleStorage = require_utils_localeStorage.LocaleStorage;
161
164
  exports.LocaleStorageClient = require_utils_localeStorage.LocaleStorageClient;
162
165
  exports.LocaleStorageServer = require_utils_localeStorage.LocaleStorageServer;
163
166
  exports.NAMED_CODES_TO_UNICODE = require_markdown_constants.NAMED_CODES_TO_UNICODE;
167
+ exports.NORMALIZE_WHITESPACE_R = require_markdown_constants.NORMALIZE_WHITESPACE_R;
164
168
  exports.NP_TABLE_R = require_markdown_constants.NP_TABLE_R;
165
169
  exports.ORDERED = require_markdown_constants.ORDERED;
166
170
  exports.ORDERED_LIST_BULLET = require_markdown_constants.ORDERED_LIST_BULLET;
@@ -242,7 +246,7 @@ exports.get = require_markdown_utils.get;
242
246
  exports.getBasePlugins = require_interpreter_getContent_getContent.getBasePlugins;
243
247
  exports.getBrowserLocale = require_localization_getBrowserLocale.getBrowserLocale;
244
248
  exports.getCachedIntl = require_utils_intl.getCachedIntl;
245
- exports.getCanonicalPath = require_localization_rewriteUtils.getCanonicalPath;
249
+ exports.getCanonicalPath = require_localization_getCanonicalPath.getCanonicalPath;
246
250
  exports.getCondition = require_interpreter_getCondition.getCondition;
247
251
  exports.getContent = require_interpreter_getContent_getContent.getContent;
248
252
  exports.getContentNodeByKeyPath = require_dictionaryManipulator_getContentNodeByKeyPath.getContentNodeByKeyPath;
@@ -308,7 +312,7 @@ exports.getPreloadLocale = require_localization_resolveBrowserLocale.getPreloadL
308
312
  exports.getPreloadedDictionary = require_dictionaryManipulator_preloadedDynamicLoader.getPreloadedDictionary;
309
313
  exports.getReplacedValuesContent = require_deepTransformPlugins_getReplacedValuesContent.getReplacedValuesContent;
310
314
  exports.getRewritePath = require_localization_rewriteUtils.getRewritePath;
311
- exports.getRewriteRules = require_localization_rewriteUtils.getRewriteRules;
315
+ exports.getRewriteRules = require_localization_rewriteMatch.getRewriteRules;
312
316
  exports.getSelect = require_interpreter_getSelect.getSelect;
313
317
  exports.getSplittedContent = require_deepTransformPlugins_getSplittedContent.getSplittedContent;
314
318
  exports.getSplittedDictionaryContent = require_deepTransformPlugins_getSplittedContent.getSplittedDictionaryContent;
@@ -0,0 +1,52 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_localization_rewriteMatch = require('./rewriteMatch.cjs');
3
+ let _intlayer_config_built = require("@intlayer/config/built");
4
+
5
+ //#region src/localization/getCanonicalPath.ts
6
+ /**
7
+ * Decodes percent-encoding so an encoded pathname
8
+ * (`/doc/%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/v8`, as `URL.pathname` and the
9
+ * router hand it over) matches a rewrite pattern written with its literal
10
+ * characters (`/doc/リリース/v8`). Reserved delimiters stay encoded, and a path
11
+ * with no escape — or a malformed one — is returned untouched.
12
+ */
13
+ const decodePath = (path) => {
14
+ if (!path.includes("%")) return path;
15
+ try {
16
+ return decodeURI(path);
17
+ } catch {
18
+ return path;
19
+ }
20
+ };
21
+ /**
22
+ * Given a localized URL (e.g., "/produits/123"), finds the canonical internal path (e.g., "/products/123").
23
+ * If locale is provided, only check for that locale. Otherwise, check for all locales.
24
+ *
25
+ * The lookup is encoding-insensitive: a percent-encoded path matches a pattern
26
+ * written with literal (non-ASCII) characters.
27
+ *
28
+ * @param localizedPath - The path as seen in the browser, without locale prefix.
29
+ * @param locale - Restricts the lookup to that locale's rules. Defaults to every locale.
30
+ * @param rewriteRules - Raw `routing.rewrite` configuration or already-normalized
31
+ * rules. Defaults to the project configuration's `routing.rewrite`.
32
+ */
33
+ const getCanonicalPath = (localizedPath, locale, rewriteRules) => {
34
+ const rules = require_localization_rewriteMatch.getRewriteRules(rewriteRules ?? _intlayer_config_built.routing?.rewrite, "url");
35
+ if (!rules || process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return localizedPath;
36
+ const pathToMatch = decodePath(localizedPath);
37
+ for (const rule of rules.rules) {
38
+ const { canonical, localized } = rule;
39
+ const localesToCheck = locale ? [locale] : Object.keys(localized);
40
+ for (const locale of localesToCheck) {
41
+ const localizedPattern = localized[locale];
42
+ if (!localizedPattern) continue;
43
+ const params = require_localization_rewriteMatch.extractParams(pathToMatch, localizedPattern);
44
+ if (params) return require_localization_rewriteMatch.fillPath(canonical, params);
45
+ }
46
+ }
47
+ return localizedPath;
48
+ };
49
+
50
+ //#endregion
51
+ exports.getCanonicalPath = getCanonicalPath;
52
+ //# sourceMappingURL=getCanonicalPath.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCanonicalPath.cjs","names":["getRewriteRules","routing","extractParams","fillPath"],"sources":["../../../src/localization/getCanonicalPath.ts"],"sourcesContent":["import { routing } from '@intlayer/config/built';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type { LocalesValues } from '@intlayer/types/module_augmentation';\nimport { extractParams, fillPath, getRewriteRules } from './rewriteMatch';\n\n/**\n * Decodes percent-encoding so an encoded pathname\n * (`/doc/%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9/v8`, as `URL.pathname` and the\n * router hand it over) matches a rewrite pattern written with its literal\n * characters (`/doc/リリース/v8`). Reserved delimiters stay encoded, and a path\n * with no escape — or a malformed one — is returned untouched.\n */\nconst decodePath = (path: string): string => {\n if (!path.includes('%')) return path;\n\n try {\n return decodeURI(path);\n } catch {\n return path;\n }\n};\n\n/**\n * Given a localized URL (e.g., \"/produits/123\"), finds the canonical internal path (e.g., \"/products/123\").\n * If locale is provided, only check for that locale. Otherwise, check for all locales.\n *\n * The lookup is encoding-insensitive: a percent-encoded path matches a pattern\n * written with literal (non-ASCII) characters.\n *\n * @param localizedPath - The path as seen in the browser, without locale prefix.\n * @param locale - Restricts the lookup to that locale's rules. Defaults to every locale.\n * @param rewriteRules - Raw `routing.rewrite` configuration or already-normalized\n * rules. Defaults to the project configuration's `routing.rewrite`.\n */\nexport const getCanonicalPath = <\n const Path extends string,\n const Locale extends LocalesValues = LocalesValues,\n>(\n localizedPath: Path,\n locale?: Locale,\n rewriteRules?: RoutingConfig['rewrite'] | RewriteRules\n): string => {\n const rules = getRewriteRules(rewriteRules ?? routing?.rewrite, 'url');\n\n if (\n !rules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return localizedPath;\n\n const pathToMatch = decodePath(localizedPath);\n\n for (const rule of rules.rules) {\n const { canonical, localized } = rule;\n const localesToCheck = locale ? [locale] : Object.keys(localized);\n\n for (const locale of localesToCheck) {\n const localizedPattern = localized[locale as keyof typeof localized];\n\n if (!localizedPattern) continue;\n\n const params = extractParams(pathToMatch, localizedPattern);\n\n if (params) {\n return fillPath(canonical, params);\n }\n }\n }\n\n return localizedPath;\n};\n"],"mappings":";;;;;;;;;;;;AAYA,MAAM,cAAc,SAAyB;CAC3C,IAAI,CAAC,KAAK,SAAS,GAAG,GAAG,OAAO;CAEhC,IAAI;EACF,OAAO,UAAU,IAAI;CACvB,QAAQ;EACN,OAAO;CACT;AACF;;;;;;;;;;;;;AAcA,MAAa,oBAIX,eACA,QACA,iBACW;CACX,MAAM,QAAQA,kDAAgB,gBAAgBC,gCAAS,SAAS,KAAK;CAErE,IACE,CAAC,SACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,MAAM,cAAc,WAAW,aAAa;CAE5C,KAAK,MAAM,QAAQ,MAAM,OAAO;EAC9B,MAAM,EAAE,WAAW,cAAc;EACjC,MAAM,iBAAiB,SAAS,CAAC,MAAM,IAAI,OAAO,KAAK,SAAS;EAEhE,KAAK,MAAM,UAAU,gBAAgB;GACnC,MAAM,mBAAmB,UAAU;GAEnC,IAAI,CAAC,kBAAkB;GAEvB,MAAM,SAASC,gDAAc,aAAa,gBAAgB;GAE1D,IAAI,QACF,OAAOC,2CAAS,WAAW,MAAM;EAErC;CACF;CAEA,OAAO;AACT"}
@@ -0,0 +1,12 @@
1
+ const require_localization_getCanonicalPath = require('./getCanonicalPath.cjs');
2
+ let vitest = require("vitest");
3
+
4
+ //#region src/localization/getCanonicalPath.test-d.ts
5
+ (0, vitest.describe)("getCanonicalPath", () => {
6
+ (0, vitest.it)("should accept an omitted locale (checks every locale)", () => {
7
+ (0, vitest.expectTypeOf)(require_localization_getCanonicalPath.getCanonicalPath("/a-propos")).toEqualTypeOf();
8
+ });
9
+ });
10
+
11
+ //#endregion
12
+ //# sourceMappingURL=getCanonicalPath.test-d.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getCanonicalPath.test-d.cjs","names":["describe","getCanonicalPath"],"sources":["../../../src/localization/getCanonicalPath.test-d.ts"],"sourcesContent":["import { describe, expectTypeOf, it } from 'vitest';\nimport { getCanonicalPath } from './getCanonicalPath';\n\ndescribe('getCanonicalPath', () => {\n it('should accept an omitted locale (checks every locale)', () => {\n expectTypeOf(getCanonicalPath('/a-propos')).toEqualTypeOf<string>();\n });\n});\n"],"mappings":";;;;IAGAA,iBAAS,0BAA0B;CACjC,eAAG,+DAA+D;EAChE,yBAAaC,uDAAiB,WAAW,CAAC,CAAC,CAAC,cAAsB;CACpE,CAAC;AACH,CAAC"}
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_localization_getPathWithoutLocale = require('./getPathWithoutLocale.cjs');
3
+ const require_localization_rewriteMatch = require('./rewriteMatch.cjs');
4
+ const require_localization_getCanonicalPath = require('./getCanonicalPath.cjs');
3
5
  const require_localization_getPrefix = require('./getPrefix.cjs');
4
6
  const require_localization_rewriteUtils = require('./rewriteUtils.cjs');
5
7
  let _intlayer_config_built = require("@intlayer/config/built");
@@ -51,9 +53,9 @@ let _intlayer_config_built = require("@intlayer/config/built");
51
53
  const getLocalizedPath = (canonicalPath, locale = _intlayer_config_built.internationalization?.defaultLocale, options = {}) => {
52
54
  const { defaultLocale, mode, locales, rewrite, domains } = require_localization_getPrefix.resolveRoutingConfig(options);
53
55
  const pathWithoutLocale = require_localization_getPathWithoutLocale.getPathWithoutLocale(canonicalPath, locales);
54
- const rewriteRules = require_localization_rewriteUtils.getRewriteRules(rewrite, "url");
56
+ const rewriteRules = require_localization_rewriteMatch.getRewriteRules(rewrite, "url");
55
57
  const parsedPath = new URL(pathWithoutLocale, "http://e.com");
56
- const translatedPathname = require_localization_rewriteUtils.resolveLocalizedPath(require_localization_rewriteUtils.getCanonicalPath(parsedPath.pathname, void 0, rewriteRules), locale, rewriteRules).path;
58
+ const translatedPathname = require_localization_rewriteUtils.resolveLocalizedPath(require_localization_getCanonicalPath.getCanonicalPath(parsedPath.pathname, void 0, rewriteRules), locale, rewriteRules).path;
57
59
  if (!(process.env.INTLAYER_ROUTING_MODE && process.env.INTLAYER_ROUTING_MODE !== "no-prefix") && mode === "no-prefix") return `${translatedPathname}${parsedPath.search}${parsedPath.hash}`;
58
60
  if (!(process.env.INTLAYER_ROUTING_MODE && process.env.INTLAYER_ROUTING_MODE !== "search-params") && mode === "search-params") {
59
61
  const searchParams = new URLSearchParams(parsedPath.search);
@@ -1 +1 @@
1
- {"version":3,"file":"getLocalizedPath.cjs","names":["internationalization","resolveRoutingConfig","getPathWithoutLocale","getRewriteRules","resolveLocalizedPath","getCanonicalPath","getPrefix"],"sources":["../../../src/localization/getLocalizedPath.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type {\n LocalesValues,\n LocalizedPathname,\n ResolvedDefaultLocale,\n} from '@intlayer/types/module_augmentation';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport {\n getPrefix,\n type RoutingOptions,\n resolveRoutingConfig,\n} from './getPrefix';\nimport {\n getCanonicalPath,\n getRewriteRules,\n resolveLocalizedPath,\n} from './rewriteUtils';\n\n/**\n * Localizes an application path for a locale: resolves the `routing.rewrite`\n * rules, then applies the locale representation of the routing mode — a path\n * prefix, a `locale` search parameter, or nothing at all.\n *\n * Any query string and hash of the input are preserved.\n *\n * This is the relative half of {@link getLocalizedUrl}, which builds on it to\n * add an origin and cross-domain routing. For a relative input both return the\n * same value; this one never returns an absolute URL — the origin of an\n * absolute input is dropped and only its path is localized.\n *\n * Use `resolveLocalizedPath` instead to apply the rewrite rules alone, without\n * any locale representation.\n *\n * @example\n * ```ts\n * // routing: { mode: 'prefix-no-default', rewrite: { '/about': { fr: '/a-propos' } } }\n * getLocalizedPath('/about', 'fr'); // '/fr/a-propos'\n * getLocalizedPath('/about', 'en'); // '/about' (default locale, no prefix)\n * getLocalizedPath('/', 'fr'); // '/fr'\n * getLocalizedPath('/contact', 'fr'); // '/fr/contact' (no rewrite rule matches)\n * getLocalizedPath('https://intlayer.org/about', 'fr'); // '/fr/a-propos' (origin dropped)\n *\n * // routing: { domains: { zh: 'intlayer.cn' } } — zh is alone on that hostname\n * getLocalizedPath('/about', 'zh'); // '/about' (the domain identifies the locale)\n *\n * // Manual rules, bypassing the configuration\n * getLocalizedPath('/contact', 'fr', {\n * rewrite: { '/contact': { fr: '/contactez-nous' } },\n * });\n * // '/fr/contactez-nous'\n * ```\n *\n * @param canonicalPath - The internal application path (e.g. `/about`, `/product/123`).\n * An absolute URL is accepted; only its path, query and hash are kept.\n * @param locale - The target locale. Defaults to the configured default locale.\n * @param options - Routing overrides (`locales`, `defaultLocale`, `mode`, `rewrite`,\n * `domains`). Each one defaults to the project configuration. `domains` only\n * suppresses the prefix of a locale served from its own domain — the origin\n * itself is never emitted.\n * @returns The localized path for the target locale.\n */\nexport const getLocalizedPath = <\n const CanonicalPath extends string,\n const CurrentLocale extends LocalesValues = ResolvedDefaultLocale,\n>(\n canonicalPath: CanonicalPath,\n locale: CurrentLocale = internationalization?.defaultLocale as CurrentLocale,\n options: RoutingOptions = {}\n): LocalizedPathname<CanonicalPath, CurrentLocale> => {\n const { defaultLocale, mode, locales, rewrite, domains } =\n resolveRoutingConfig(options);\n\n const pathWithoutLocale = getPathWithoutLocale(canonicalPath, locales);\n const rewriteRules = getRewriteRules(rewrite, 'url');\n\n // Parsed against a dummy origin to split the path from its query and hash.\n // An absolute input parses on its own, and only its path is kept.\n const parsedPath = new URL(pathWithoutLocale, 'http://e.com');\n\n const translatedPathname = resolveLocalizedPath(\n getCanonicalPath(parsedPath.pathname, undefined, rewriteRules),\n locale as Locale,\n rewriteRules\n ).path;\n\n if (\n !(\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'no-prefix'\n ) &&\n mode === 'no-prefix'\n ) {\n return `${translatedPathname}${parsedPath.search}${parsedPath.hash}` as LocalizedPathname<\n CanonicalPath,\n CurrentLocale\n >;\n }\n\n if (\n !(\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'search-params'\n ) &&\n mode === 'search-params'\n ) {\n const searchParams = new URLSearchParams(parsedPath.search);\n\n searchParams.set('locale', locale.toString());\n\n const queryParams = searchParams.toString();\n\n return `${translatedPathname}${queryParams ? `?${queryParams}` : ''}${parsedPath.hash}` as LocalizedPathname<\n CanonicalPath,\n CurrentLocale\n >;\n }\n\n const { prefix } = getPrefix(locale, {\n defaultLocale,\n mode,\n locales,\n domains,\n });\n\n let localizedPath = `/${prefix}${translatedPathname}`.replace(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n return `${localizedPath}${parsedPath.search}${parsedPath.hash}` as LocalizedPathname<\n CanonicalPath,\n CurrentLocale\n >;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8DA,MAAa,oBAIX,eACA,SAAwBA,6CAAsB,eAC9C,UAA0B,CAAC,MACyB;CACpD,MAAM,EAAE,eAAe,MAAM,SAAS,SAAS,YAC7CC,oDAAqB,OAAO;CAE9B,MAAM,oBAAoBC,+DAAqB,eAAe,OAAO;CACrE,MAAM,eAAeC,kDAAgB,SAAS,KAAK;CAInD,MAAM,aAAa,IAAI,IAAI,mBAAmB,cAAc;CAE5D,MAAM,qBAAqBC,uDACzBC,mDAAiB,WAAW,UAAU,QAAW,YAAY,GAC7D,QACA,YACF,CAAC,CAAC;CAEF,IACE,EACE,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B,gBAExC,SAAS,aAET,OAAO,GAAG,qBAAqB,WAAW,SAAS,WAAW;CAMhE,IACE,EACE,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B,oBAExC,SAAS,iBACT;EACA,MAAM,eAAe,IAAI,gBAAgB,WAAW,MAAM;EAE1D,aAAa,IAAI,UAAU,OAAO,SAAS,CAAC;EAE5C,MAAM,cAAc,aAAa,SAAS;EAE1C,OAAO,GAAG,qBAAqB,cAAc,IAAI,gBAAgB,KAAK,WAAW;CAInF;CAEA,MAAM,EAAE,WAAWC,yCAAU,QAAQ;EACnC;EACA;EACA;EACA;CACF,CAAC;CAED,IAAI,gBAAgB,IAAI,SAAS,qBAAqB,QAAQ,QAAQ,GAAG;CAEzE,IAAI,cAAc,SAAS,KAAK,cAAc,SAAS,GAAG,GACxD,gBAAgB,cAAc,MAAM,GAAG,EAAE;CAG3C,OAAO,GAAG,gBAAgB,WAAW,SAAS,WAAW;AAI3D"}
1
+ {"version":3,"file":"getLocalizedPath.cjs","names":["internationalization","resolveRoutingConfig","getPathWithoutLocale","getRewriteRules","resolveLocalizedPath","getCanonicalPath","getPrefix"],"sources":["../../../src/localization/getLocalizedPath.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { Locale } from '@intlayer/types/allLocales';\nimport type {\n LocalesValues,\n LocalizedPathname,\n ResolvedDefaultLocale,\n} from '@intlayer/types/module_augmentation';\nimport { getCanonicalPath } from './getCanonicalPath';\nimport { getPathWithoutLocale } from './getPathWithoutLocale';\nimport {\n getPrefix,\n type RoutingOptions,\n resolveRoutingConfig,\n} from './getPrefix';\nimport { getRewriteRules } from './rewriteMatch';\nimport { resolveLocalizedPath } from './rewriteUtils';\n\n/**\n * Localizes an application path for a locale: resolves the `routing.rewrite`\n * rules, then applies the locale representation of the routing mode — a path\n * prefix, a `locale` search parameter, or nothing at all.\n *\n * Any query string and hash of the input are preserved.\n *\n * This is the relative half of {@link getLocalizedUrl}, which builds on it to\n * add an origin and cross-domain routing. For a relative input both return the\n * same value; this one never returns an absolute URL — the origin of an\n * absolute input is dropped and only its path is localized.\n *\n * Use `resolveLocalizedPath` instead to apply the rewrite rules alone, without\n * any locale representation.\n *\n * @example\n * ```ts\n * // routing: { mode: 'prefix-no-default', rewrite: { '/about': { fr: '/a-propos' } } }\n * getLocalizedPath('/about', 'fr'); // '/fr/a-propos'\n * getLocalizedPath('/about', 'en'); // '/about' (default locale, no prefix)\n * getLocalizedPath('/', 'fr'); // '/fr'\n * getLocalizedPath('/contact', 'fr'); // '/fr/contact' (no rewrite rule matches)\n * getLocalizedPath('https://intlayer.org/about', 'fr'); // '/fr/a-propos' (origin dropped)\n *\n * // routing: { domains: { zh: 'intlayer.cn' } } — zh is alone on that hostname\n * getLocalizedPath('/about', 'zh'); // '/about' (the domain identifies the locale)\n *\n * // Manual rules, bypassing the configuration\n * getLocalizedPath('/contact', 'fr', {\n * rewrite: { '/contact': { fr: '/contactez-nous' } },\n * });\n * // '/fr/contactez-nous'\n * ```\n *\n * @param canonicalPath - The internal application path (e.g. `/about`, `/product/123`).\n * An absolute URL is accepted; only its path, query and hash are kept.\n * @param locale - The target locale. Defaults to the configured default locale.\n * @param options - Routing overrides (`locales`, `defaultLocale`, `mode`, `rewrite`,\n * `domains`). Each one defaults to the project configuration. `domains` only\n * suppresses the prefix of a locale served from its own domain — the origin\n * itself is never emitted.\n * @returns The localized path for the target locale.\n */\nexport const getLocalizedPath = <\n const CanonicalPath extends string,\n const CurrentLocale extends LocalesValues = ResolvedDefaultLocale,\n>(\n canonicalPath: CanonicalPath,\n locale: CurrentLocale = internationalization?.defaultLocale as CurrentLocale,\n options: RoutingOptions = {}\n): LocalizedPathname<CanonicalPath, CurrentLocale> => {\n const { defaultLocale, mode, locales, rewrite, domains } =\n resolveRoutingConfig(options);\n\n const pathWithoutLocale = getPathWithoutLocale(canonicalPath, locales);\n const rewriteRules = getRewriteRules(rewrite, 'url');\n\n // Parsed against a dummy origin to split the path from its query and hash.\n // An absolute input parses on its own, and only its path is kept.\n const parsedPath = new URL(pathWithoutLocale, 'http://e.com');\n\n const translatedPathname = resolveLocalizedPath(\n getCanonicalPath(parsedPath.pathname, undefined, rewriteRules),\n locale as Locale,\n rewriteRules\n ).path;\n\n if (\n !(\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'no-prefix'\n ) &&\n mode === 'no-prefix'\n ) {\n return `${translatedPathname}${parsedPath.search}${parsedPath.hash}` as LocalizedPathname<\n CanonicalPath,\n CurrentLocale\n >;\n }\n\n if (\n !(\n process.env.INTLAYER_ROUTING_MODE &&\n process.env.INTLAYER_ROUTING_MODE !== 'search-params'\n ) &&\n mode === 'search-params'\n ) {\n const searchParams = new URLSearchParams(parsedPath.search);\n\n searchParams.set('locale', locale.toString());\n\n const queryParams = searchParams.toString();\n\n return `${translatedPathname}${queryParams ? `?${queryParams}` : ''}${parsedPath.hash}` as LocalizedPathname<\n CanonicalPath,\n CurrentLocale\n >;\n }\n\n const { prefix } = getPrefix(locale, {\n defaultLocale,\n mode,\n locales,\n domains,\n });\n\n let localizedPath = `/${prefix}${translatedPathname}`.replace(/\\/+/g, '/');\n\n if (localizedPath.length > 1 && localizedPath.endsWith('/')) {\n localizedPath = localizedPath.slice(0, -1);\n }\n\n return `${localizedPath}${parsedPath.search}${parsedPath.hash}` as LocalizedPathname<\n CanonicalPath,\n CurrentLocale\n >;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4DA,MAAa,oBAIX,eACA,SAAwBA,6CAAsB,eAC9C,UAA0B,CAAC,MACyB;CACpD,MAAM,EAAE,eAAe,MAAM,SAAS,SAAS,YAC7CC,oDAAqB,OAAO;CAE9B,MAAM,oBAAoBC,+DAAqB,eAAe,OAAO;CACrE,MAAM,eAAeC,kDAAgB,SAAS,KAAK;CAInD,MAAM,aAAa,IAAI,IAAI,mBAAmB,cAAc;CAE5D,MAAM,qBAAqBC,uDACzBC,uDAAiB,WAAW,UAAU,QAAW,YAAY,GAC7D,QACA,YACF,CAAC,CAAC;CAEF,IACE,EACE,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B,gBAExC,SAAS,aAET,OAAO,GAAG,qBAAqB,WAAW,SAAS,WAAW;CAMhE,IACE,EACE,QAAQ,IAAI,yBACZ,QAAQ,IAAI,0BAA0B,oBAExC,SAAS,iBACT;EACA,MAAM,eAAe,IAAI,gBAAgB,WAAW,MAAM;EAE1D,aAAa,IAAI,UAAU,OAAO,SAAS,CAAC;EAE5C,MAAM,cAAc,aAAa,SAAS;EAE1C,OAAO,GAAG,qBAAqB,cAAc,IAAI,gBAAgB,KAAK,WAAW;CAInF;CAEA,MAAM,EAAE,WAAWC,yCAAU,QAAQ;EACnC;EACA;EACA;EACA;CACF,CAAC;CAED,IAAI,gBAAgB,IAAI,SAAS,qBAAqB,QAAQ,QAAQ,GAAG;CAEzE,IAAI,cAAc,SAAS,KAAK,cAAc,SAAS,GAAG,GACxD,gBAAgB,cAAc,MAAM,GAAG,EAAE;CAG3C,OAAO,GAAG,gBAAgB,WAAW,SAAS,WAAW;AAI3D"}
@@ -2,6 +2,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_localization_getPathWithoutLocale = require('./getPathWithoutLocale.cjs');
3
3
  const require_localization_comparePaths = require('./comparePaths.cjs');
4
4
  const require_localization_domainUtils = require('./domainUtils.cjs');
5
+ const require_localization_rewriteMatch = require('./rewriteMatch.cjs');
6
+ const require_localization_getCanonicalPath = require('./getCanonicalPath.cjs');
5
7
  const require_localization_getPrefix = require('./getPrefix.cjs');
6
8
  const require_localization_rewriteUtils = require('./rewriteUtils.cjs');
7
9
  const require_localization_getLocalizedPath = require('./getLocalizedPath.cjs');
@@ -26,7 +28,7 @@ exports.formatProxyEnabledMessage = require_localization_proxyMode.formatProxyEn
26
28
  exports.generateSitemap = require_localization_generateSitemap.generateSitemap;
27
29
  exports.generateSitemapUrl = require_localization_generateSitemap.generateSitemapUrl;
28
30
  exports.getBrowserLocale = require_localization_getBrowserLocale.getBrowserLocale;
29
- exports.getCanonicalPath = require_localization_rewriteUtils.getCanonicalPath;
31
+ exports.getCanonicalPath = require_localization_getCanonicalPath.getCanonicalPath;
30
32
  exports.getDomainHostname = require_localization_domainUtils.getDomainHostname;
31
33
  exports.getDomainOrigin = require_localization_domainUtils.getDomainOrigin;
32
34
  exports.getHTMLTextDir = require_localization_getHTMLTextDir.getHTMLTextDir;
@@ -43,7 +45,7 @@ exports.getPathWithoutLocale = require_localization_getPathWithoutLocale.getPath
43
45
  exports.getPrefix = require_localization_getPrefix.getPrefix;
44
46
  exports.getPreloadLocale = require_localization_resolveBrowserLocale.getPreloadLocale;
45
47
  exports.getRewritePath = require_localization_rewriteUtils.getRewritePath;
46
- exports.getRewriteRules = require_localization_rewriteUtils.getRewriteRules;
48
+ exports.getRewriteRules = require_localization_rewriteMatch.getRewriteRules;
47
49
  exports.isDeclaredLocale = require_localization_getPrefix.isDeclaredLocale;
48
50
  exports.isLocaleExclusiveOnDomain = require_localization_domainUtils.isLocaleExclusiveOnDomain;
49
51
  exports.isProxyStorageLocaleEnabled = require_localization_proxyMode.isProxyStorageLocaleEnabled;
@@ -0,0 +1,52 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ //#region src/localization/rewriteMatch.ts
3
+ /**
4
+ * Normalizes legacy Record format or extracts specialized rules from RewriteObject.
5
+ *
6
+ * Idempotent: already-normalized rules are handed back untouched, so a caller
7
+ * holding resolved rules can pass them on without re-normalizing.
8
+ */
9
+ const getRewriteRules = (rewrite, context = "url") => {
10
+ if (!rewrite || process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return void 0;
11
+ if (Array.isArray(rewrite.rules)) return rewrite;
12
+ if ("url" in rewrite) return rewrite[context];
13
+ return { rules: Object.entries(rewrite).map(([canonical, localized]) => ({
14
+ canonical: canonical.startsWith("/") ? canonical.replace(/\[([^\]]+)\]/g, ":$1") : `/${canonical.replace(/\[([^\]]+)\]/g, ":$1")}`,
15
+ localized: Object.fromEntries(Object.entries(localized).map(([locale, pattern]) => {
16
+ return [locale, pattern?.startsWith("/") ? pattern.replace(/\[([^\]]+)\]/g, ":$1") : `/${(pattern || "").replace(/\[([^\]]+)\]/g, ":$1")}`];
17
+ }))
18
+ })) };
19
+ };
20
+ /**
21
+ * Converts normalized pattern to Regex.
22
+ * Internal syntax supports:
23
+ * - :param -> ([^/]+) (one segment)
24
+ * - :param* -> (.*) (zero or more segments)
25
+ * - :param+ -> (.+) (one or more segments)
26
+ * - :param? -> ([^/]*) (zero or one segment)
27
+ */
28
+ const patternToRegex = (pattern) => {
29
+ const regexString = pattern.replace(/\//g, "\\/").replace(/\\\/:(?:[^/\\*+?]+)\*/g, "(?:\\/(.*))?").replace(/\\\/:(?:[^/\\*+?]+)\?/g, "(?:\\/([^\\/]+))?").replace(/:([^/\\*+?]+)\*/g, "(.*)").replace(/:([^/\\*+?]+)\?/g, "([^\\/]*)").replace(/:([^/\\*+?]+)\+/g, "(.+)").replace(/:([^/\\*+?]+)/g, "([^\\/]+)");
30
+ return new RegExp(`^${regexString}$`);
31
+ };
32
+ /**
33
+ * Replaces route parameters in a path with provided values.
34
+ */
35
+ const fillPath = (pattern, params) => {
36
+ let index = 0;
37
+ return pattern.replace(/:([^/\\*+?]+)[*+?]?/g, () => params[index++] ?? "").replace(/\/+/g, "/").replace(/\/$/, "") || "/";
38
+ };
39
+ /**
40
+ * Extract values from a URL based on a pattern.
41
+ */
42
+ const extractParams = (url, pattern) => {
43
+ const regex = patternToRegex(pattern);
44
+ const match = url.match(regex);
45
+ return match ? match.slice(1) : null;
46
+ };
47
+
48
+ //#endregion
49
+ exports.extractParams = extractParams;
50
+ exports.fillPath = fillPath;
51
+ exports.getRewriteRules = getRewriteRules;
52
+ //# sourceMappingURL=rewriteMatch.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewriteMatch.cjs","names":["legacyRules"],"sources":["../../../src/localization/rewriteMatch.ts"],"sourcesContent":["import type {\n RewriteObject,\n RewriteRules,\n RoutingConfig,\n} from '@intlayer/types/config';\n\n/**\n * Normalizes legacy Record format or extracts specialized rules from RewriteObject.\n *\n * Idempotent: already-normalized rules are handed back untouched, so a caller\n * holding resolved rules can pass them on without re-normalizing.\n */\nexport const getRewriteRules = <\n const Context extends keyof RewriteObject = 'url',\n>(\n rewrite: RoutingConfig['rewrite'] | RewriteRules,\n context: Context = 'url' as Context\n): RewriteRules | undefined => {\n if (\n !rewrite ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return undefined;\n\n if (Array.isArray((rewrite as RewriteRules).rules)) {\n return rewrite as RewriteRules;\n }\n\n if ('url' in rewrite) {\n return (rewrite as RewriteObject)[context];\n }\n\n // Normalize legacy format\n const legacyRules = rewrite as Record<string, Record<string, string>>;\n\n return {\n rules: Object.entries(legacyRules).map(([canonical, localized]) => ({\n // Normalize canonical path\n canonical: canonical.startsWith('/')\n ? canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')}`,\n\n // Normalize localized path\n localized: Object.fromEntries(\n Object.entries(localized).map(([locale, pattern]) => {\n const normalizedPattern = pattern?.startsWith('/')\n ? pattern.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${(pattern || '').replace(/\\[([^\\]]+)\\]/g, ':$1')}`;\n return [locale, normalizedPattern];\n })\n ),\n })),\n };\n};\n\n/**\n * Converts normalized pattern to Regex.\n * Internal syntax supports:\n * - :param -> ([^/]+) (one segment)\n * - :param* -> (.*) (zero or more segments)\n * - :param+ -> (.+) (one or more segments)\n * - :param? -> ([^/]*) (zero or one segment)\n */\nconst patternToRegex = (pattern: string) => {\n const regexString = pattern\n .replace(/\\//g, '\\\\/') // Escape slashes\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\*/g, '(?:\\\\/(.*))?') // /:param*\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\?/g, '(?:\\\\/([^\\\\/]+))?') // /:param?\n .replace(/:([^/\\\\*+?]+)\\*/g, '(.*)') // :param* (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\?/g, '([^\\\\/]*)') // :param? (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\+/g, '(.+)') // :param+\n .replace(/:([^/\\\\*+?]+)/g, '([^\\\\/]+)'); // :param\n\n return new RegExp(`^${regexString}$`);\n};\n\n/**\n * Replaces route parameters in a path with provided values.\n */\nexport const fillPath = (pattern: string, params: string[]) => {\n let index = 0;\n return (\n pattern\n .replace(/:([^/\\\\*+?]+)[*+?]?/g, () => params[index++] ?? '')\n .replace(/\\/+/g, '/')\n .replace(/\\/$/, '') || '/'\n );\n};\n\n/**\n * Extract values from a URL based on a pattern.\n */\nexport const extractParams = (\n url: string,\n pattern: string\n): string[] | null => {\n const regex = patternToRegex(pattern);\n const match = url.match(regex);\n return match ? match.slice(1) : null;\n};\n"],"mappings":";;;;;;;;AAYA,MAAa,mBAGX,SACA,UAAmB,UACU;CAC7B,IACE,CAAC,WACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,IAAI,MAAM,QAAS,QAAyB,KAAK,GAC/C,OAAO;CAGT,IAAI,SAAS,SACX,OAAQ,QAA0B;CAMpC,OAAO,EACL,OAAO,OAAO,QAAQA,OAAW,CAAC,CAAC,KAAK,CAAC,WAAW,gBAAgB;EAElE,WAAW,UAAU,WAAW,GAAG,IAC/B,UAAU,QAAQ,iBAAiB,KAAK,IACxC,IAAI,UAAU,QAAQ,iBAAiB,KAAK;EAGhD,WAAW,OAAO,YAChB,OAAO,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,aAAa;GAInD,OAAO,CAAC,QAHkB,SAAS,WAAW,GAAG,IAC7C,QAAQ,QAAQ,iBAAiB,KAAK,IACtC,KAAK,WAAW,GAAE,CAAE,QAAQ,iBAAiB,KAAK,GACrB;EACnC,CAAC,CACH;CACF,EAAE,EACJ;AACF;;;;;;;;;AAUA,MAAM,kBAAkB,YAAoB;CAC1C,MAAM,cAAc,QACjB,QAAQ,OAAO,KAAK,CAAC,CACrB,QAAQ,0BAA0B,cAAc,CAAC,CACjD,QAAQ,0BAA0B,mBAAmB,CAAC,CACtD,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,oBAAoB,WAAW,CAAC,CACxC,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,kBAAkB,WAAW;CAExC,OAAO,IAAI,OAAO,IAAI,YAAY,EAAE;AACtC;;;;AAKA,MAAa,YAAY,SAAiB,WAAqB;CAC7D,IAAI,QAAQ;CACZ,OACE,QACG,QAAQ,8BAA8B,OAAO,YAAY,EAAE,CAAC,CAC5D,QAAQ,QAAQ,GAAG,CAAC,CACpB,QAAQ,OAAO,EAAE,KAAK;AAE7B;;;;AAKA,MAAa,iBACX,KACA,YACoB;CACpB,MAAM,QAAQ,eAAe,OAAO;CACpC,MAAM,QAAQ,IAAI,MAAM,KAAK;CAC7B,OAAO,QAAQ,MAAM,MAAM,CAAC,IAAI;AAClC"}
@@ -1,70 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
+ const require_localization_rewriteMatch = require('./rewriteMatch.cjs');
3
+ const require_localization_getCanonicalPath = require('./getCanonicalPath.cjs');
2
4
  let _intlayer_config_built = require("@intlayer/config/built");
3
5
 
4
6
  //#region src/localization/rewriteUtils.ts
5
7
  /**
6
- * Normalizes legacy Record format or extracts specialized rules from RewriteObject.
7
- *
8
- * Idempotent: already-normalized rules are handed back untouched, so a caller
9
- * holding resolved rules can pass them on without re-normalizing.
10
- */
11
- const getRewriteRules = (rewrite, context = "url") => {
12
- if (!rewrite || process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return void 0;
13
- if (Array.isArray(rewrite.rules)) return rewrite;
14
- if ("url" in rewrite) return rewrite[context];
15
- return { rules: Object.entries(rewrite).map(([canonical, localized]) => ({
16
- canonical: canonical.startsWith("/") ? canonical.replace(/\[([^\]]+)\]/g, ":$1") : `/${canonical.replace(/\[([^\]]+)\]/g, ":$1")}`,
17
- localized: Object.fromEntries(Object.entries(localized).map(([locale, pattern]) => {
18
- return [locale, pattern?.startsWith("/") ? pattern.replace(/\[([^\]]+)\]/g, ":$1") : `/${(pattern || "").replace(/\[([^\]]+)\]/g, ":$1")}`];
19
- }))
20
- })) };
21
- };
22
- /**
23
- * Converts normalized pattern to Regex.
24
- * Internal syntax supports:
25
- * - :param -> ([^/]+) (one segment)
26
- * - :param* -> (.*) (zero or more segments)
27
- * - :param+ -> (.+) (one or more segments)
28
- * - :param? -> ([^/]*) (zero or one segment)
29
- */
30
- const patternToRegex = (pattern) => {
31
- const regexString = pattern.replace(/\//g, "\\/").replace(/\\\/:(?:[^/\\*+?]+)\*/g, "(?:\\/(.*))?").replace(/\\\/:(?:[^/\\*+?]+)\?/g, "(?:\\/([^\\/]+))?").replace(/:([^/\\*+?]+)\*/g, "(.*)").replace(/:([^/\\*+?]+)\?/g, "([^\\/]*)").replace(/:([^/\\*+?]+)\+/g, "(.+)").replace(/:([^/\\*+?]+)/g, "([^\\/]+)");
32
- return new RegExp(`^${regexString}$`);
33
- };
34
- /**
35
- * Replaces route parameters in a path with provided values.
36
- */
37
- const fillPath = (pattern, params) => {
38
- let index = 0;
39
- return pattern.replace(/:([^/\\*+?]+)[*+?]?/g, () => params[index++] ?? "").replace(/\/+/g, "/").replace(/\/$/, "") || "/";
40
- };
41
- /**
42
- * Extract values from a URL based on a pattern.
43
- */
44
- const extractParams = (url, pattern) => {
45
- const regex = patternToRegex(pattern);
46
- const match = url.match(regex);
47
- return match ? match.slice(1) : null;
48
- };
49
- /**
50
- * Given a localized URL (e.g., "/produits/123"), finds the canonical internal path (e.g., "/products/123").
51
- * If locale is provided, only check for that locale. Otherwise, check for all locales.
52
- */
53
- const getCanonicalPath = (localizedPath, locale, rewriteRules) => {
54
- if (!rewriteRules || process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return localizedPath;
55
- for (const rule of rewriteRules.rules) {
56
- const { canonical, localized } = rule;
57
- const localesToCheck = locale ? [locale] : Object.keys(localized);
58
- for (const loc of localesToCheck) {
59
- const localizedPattern = localized[loc];
60
- if (!localizedPattern) continue;
61
- const params = extractParams(localizedPath, localizedPattern);
62
- if (params) return fillPath(canonical, params);
63
- }
64
- }
65
- return localizedPath;
66
- };
67
- /**
68
8
  * Given a canonical path (e.g., "/products/123"), finds the localized URL pattern
69
9
  * (e.g., "/produits/123") and reports whether a rule actually matched.
70
10
  *
@@ -85,11 +25,11 @@ const resolveLocalizedPath = (canonicalPath, locale, rewriteRules) => {
85
25
  };
86
26
  for (const rule of rewriteRules.rules) {
87
27
  const { canonical, localized } = rule;
88
- const params = extractParams(canonicalPath, canonical);
28
+ const params = require_localization_rewriteMatch.extractParams(canonicalPath, canonical);
89
29
  if (params) {
90
30
  const targetPattern = localized[locale ?? _intlayer_config_built.internationalization.defaultLocale];
91
31
  if (targetPattern) return {
92
- path: fillPath(targetPattern, params),
32
+ path: require_localization_rewriteMatch.fillPath(targetPattern, params),
93
33
  isRewritten: true
94
34
  };
95
35
  }
@@ -113,17 +53,15 @@ const getInternalPath = (canonicalPath, locale) => {
113
53
  */
114
54
  const getRewritePath = (pathname, locale, rewrite) => {
115
55
  if (process.env.INTLAYER_ROUTING_REWRITE_RULES && process.env.INTLAYER_ROUTING_REWRITE_RULES === "false") return void 0;
116
- const rules = getRewriteRules(rewrite, "url");
56
+ const rules = require_localization_rewriteMatch.getRewriteRules(rewrite, "url");
117
57
  if (!rules) return void 0;
118
- const canonicalPath = getCanonicalPath(pathname, void 0, rules);
58
+ const canonicalPath = require_localization_getCanonicalPath.getCanonicalPath(pathname, void 0, rules);
119
59
  const { path: localizedPath, isRewritten } = resolveLocalizedPath(canonicalPath, locale, rules);
120
60
  if (isRewritten && localizedPath !== pathname) return localizedPath;
121
61
  };
122
62
 
123
63
  //#endregion
124
- exports.getCanonicalPath = getCanonicalPath;
125
64
  exports.getInternalPath = getInternalPath;
126
65
  exports.getRewritePath = getRewritePath;
127
- exports.getRewriteRules = getRewriteRules;
128
66
  exports.resolveLocalizedPath = resolveLocalizedPath;
129
67
  //# sourceMappingURL=rewriteUtils.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rewriteUtils.cjs","names":["legacyRules","internationalization"],"sources":["../../../src/localization/rewriteUtils.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type {\n RewriteObject,\n RewriteRules,\n RoutingConfig,\n} from '@intlayer/types/config';\nimport type {\n LocalesValues,\n ResolvedDefaultLocale,\n} from '@intlayer/types/module_augmentation';\n\n/**\n * Outcome of resolving a canonical path against the rewrite rules.\n *\n * Discriminated on `isRewritten`: when no rule matched, `path` is the very\n * input that was passed in, so a literal input keeps its literal type. Only a\n * rewritten path is computed at runtime and therefore widens to `string`.\n */\nexport type LocalizedPathResult<CanonicalPath extends string = string> =\n | { path: CanonicalPath; isRewritten: false }\n | { path: string; isRewritten: true };\n\n/** Adds the leading slash a path may be missing. */\ntype WithLeadingSlash<Path extends string> = Path extends `/${string}`\n ? Path\n : `/${Path}`;\n\n/**\n * Computes the locale-prefixed internal path for a path and a locale, mirroring\n * `getInternalPath`'s runtime behaviour: an already-prefixed path is returned\n * untouched, the root collapses to `/${Locale}` (never a trailing slash), and\n * anything else gets the prefix prepended.\n *\n * Falls back to `string` for a non-literal path, where the prefixed and\n * already-prefixed cases cannot be told apart.\n *\n * @example\n * type A = InternalPath<'/about', 'fr'>; // '/fr/about'\n * type B = InternalPath<'/', 'fr'>; // '/fr'\n * type C = InternalPath<'/fr/about', 'fr'>; // '/fr/about' (already prefixed)\n */\nexport type InternalPath<\n Path extends string,\n Locale extends string,\n> = string extends Path\n ? string\n : WithLeadingSlash<Path> extends infer Prefixed extends string\n ? Prefixed extends `/${Locale}` | `/${Locale}/${string}`\n ? Prefixed\n : Prefixed extends '/'\n ? `/${Locale}`\n : `/${Locale}${Prefixed}`\n : never;\n\n/**\n * Normalizes legacy Record format or extracts specialized rules from RewriteObject.\n *\n * Idempotent: already-normalized rules are handed back untouched, so a caller\n * holding resolved rules can pass them on without re-normalizing.\n */\nexport const getRewriteRules = <\n const Context extends keyof RewriteObject = 'url',\n>(\n rewrite: RoutingConfig['rewrite'] | RewriteRules,\n context: Context = 'url' as Context\n): RewriteRules | undefined => {\n if (\n !rewrite ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return undefined;\n\n if (Array.isArray((rewrite as RewriteRules).rules)) {\n return rewrite as RewriteRules;\n }\n\n if ('url' in rewrite) {\n return (rewrite as RewriteObject)[context];\n }\n\n // Normalize legacy format\n const legacyRules = rewrite as Record<string, Record<string, string>>;\n\n return {\n rules: Object.entries(legacyRules).map(([canonical, localized]) => ({\n // Normalize canonical path\n canonical: canonical.startsWith('/')\n ? canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${canonical.replace(/\\[([^\\]]+)\\]/g, ':$1')}`,\n\n // Normalize localized path\n localized: Object.fromEntries(\n Object.entries(localized).map(([locale, pattern]) => {\n const normalizedPattern = pattern?.startsWith('/')\n ? pattern.replace(/\\[([^\\]]+)\\]/g, ':$1')\n : `/${(pattern || '').replace(/\\[([^\\]]+)\\]/g, ':$1')}`;\n return [locale, normalizedPattern];\n })\n ),\n })),\n };\n};\n\n/**\n * Converts normalized pattern to Regex.\n * Internal syntax supports:\n * - :param -> ([^/]+) (one segment)\n * - :param* -> (.*) (zero or more segments)\n * - :param+ -> (.+) (one or more segments)\n * - :param? -> ([^/]*) (zero or one segment)\n */\nconst patternToRegex = (pattern: string) => {\n const regexString = pattern\n .replace(/\\//g, '\\\\/') // Escape slashes\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\*/g, '(?:\\\\/(.*))?') // /:param*\n .replace(/\\\\\\/:(?:[^/\\\\*+?]+)\\?/g, '(?:\\\\/([^\\\\/]+))?') // /:param?\n .replace(/:([^/\\\\*+?]+)\\*/g, '(.*)') // :param* (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\?/g, '([^\\\\/]*)') // :param? (if no leading slash)\n .replace(/:([^/\\\\*+?]+)\\+/g, '(.+)') // :param+\n .replace(/:([^/\\\\*+?]+)/g, '([^\\\\/]+)'); // :param\n\n return new RegExp(`^${regexString}$`);\n};\n\n/**\n * Replaces route parameters in a path with provided values.\n */\nconst fillPath = (pattern: string, params: string[]) => {\n let index = 0;\n return (\n pattern\n .replace(/:([^/\\\\*+?]+)[*+?]?/g, () => params[index++] ?? '')\n .replace(/\\/+/g, '/')\n .replace(/\\/$/, '') || '/'\n );\n};\n\n/**\n * Extract values from a URL based on a pattern.\n */\nconst extractParams = (url: string, pattern: string): string[] | null => {\n const regex = patternToRegex(pattern);\n const match = url.match(regex);\n return match ? match.slice(1) : null;\n};\n\n/**\n * Given a localized URL (e.g., \"/produits/123\"), finds the canonical internal path (e.g., \"/products/123\").\n * If locale is provided, only check for that locale. Otherwise, check for all locales.\n */\nexport const getCanonicalPath = <\n const Path extends string,\n const Locale extends LocalesValues = LocalesValues,\n>(\n localizedPath: Path,\n locale?: Locale,\n rewriteRules?: RewriteRules\n): string => {\n if (\n !rewriteRules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return localizedPath;\n\n for (const rule of rewriteRules.rules) {\n const { canonical, localized } = rule;\n const localesToCheck = locale ? [locale] : Object.keys(localized);\n\n for (const loc of localesToCheck) {\n const localizedPattern = localized[loc as keyof typeof localized];\n\n if (!localizedPattern) continue;\n\n const params = extractParams(localizedPath, localizedPattern);\n\n if (params) {\n return fillPath(canonical, params);\n }\n }\n }\n\n return localizedPath;\n};\n\n/**\n * Given a canonical path (e.g., \"/products/123\"), finds the localized URL pattern\n * (e.g., \"/produits/123\") and reports whether a rule actually matched.\n *\n * Takes already-normalized rules, so callers that resolve the rules once (proxies,\n * static emitters) can reuse them. {@link getLocalizedPath} is the user-facing\n * counterpart: it accepts the raw `routing.rewrite` configuration, defaults to the\n * project configuration, and returns the path alone.\n *\n * @param canonicalPath - The internal application path (e.g. `/product/:id`, `/about`).\n * @param locale - The target locale. Defaults to the configured default locale.\n * @param rewriteRules - Normalized rules, as returned by {@link getRewriteRules}.\n * @returns The localized path, discriminated on whether a rewrite rule matched.\n */\nexport const resolveLocalizedPath = <\n const CanonicalPath extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n canonicalPath: CanonicalPath,\n locale?: Locale,\n rewriteRules?: RewriteRules\n): LocalizedPathResult<CanonicalPath> => {\n if (\n !rewriteRules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return { path: canonicalPath, isRewritten: false };\n\n for (const rule of rewriteRules.rules) {\n const { canonical, localized } = rule;\n\n // Check if the input path matches a configured canonical pattern\n const params = extractParams(canonicalPath, canonical);\n\n if (params) {\n const targetLocale = locale ?? internationalization.defaultLocale;\n const targetPattern = localized[targetLocale as keyof typeof localized];\n\n if (targetPattern) {\n return {\n path: fillPath(targetPattern, params),\n isRewritten: true,\n };\n }\n }\n }\n\n return { path: canonicalPath, isRewritten: false };\n};\n\n/**\n * Returns the internal path for a given canonical path and locale.\n * Ensures the locale prefix is present exactly once.\n */\nexport const getInternalPath = <\n const Path extends string,\n const Locale extends LocalesValues,\n>(\n canonicalPath: Path,\n locale: Locale\n): InternalPath<Path, Locale> => {\n const pathWithLeadingSlash = canonicalPath.startsWith('/')\n ? canonicalPath\n : `/${canonicalPath}`;\n\n if (\n pathWithLeadingSlash.startsWith(`/${locale}/`) ||\n pathWithLeadingSlash === `/${locale}`\n ) {\n return pathWithLeadingSlash as InternalPath<Path, Locale>;\n }\n\n return `/${locale}${\n pathWithLeadingSlash === '/' ? '' : pathWithLeadingSlash\n }` as InternalPath<Path, Locale>;\n};\n\n/**\n * Given a current pathname and locale, returns the pretty localized path if a rewrite rule exists and the path is not already localized.\n */\nexport const getRewritePath = <\n const Path extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n pathname: Path,\n locale: Locale,\n rewrite?: RoutingConfig['rewrite']\n): string | undefined => {\n if (\n process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false'\n )\n return undefined;\n const rules = getRewriteRules(rewrite, 'url');\n if (!rules) return undefined;\n\n // Identify canonical path (relative to root, no locale prefix expected in 'url' context)\n const canonicalPath = getCanonicalPath(pathname, undefined, rules);\n\n // Get the localized path for the current locale\n const { path: localizedPath, isRewritten } = resolveLocalizedPath(\n canonicalPath,\n locale,\n rules\n );\n\n if (isRewritten && localizedPath !== pathname) {\n return localizedPath;\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;;;;;AA4DA,MAAa,mBAGX,SACA,UAAmB,UACU;CAC7B,IACE,CAAC,WACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,IAAI,MAAM,QAAS,QAAyB,KAAK,GAC/C,OAAO;CAGT,IAAI,SAAS,SACX,OAAQ,QAA0B;CAMpC,OAAO,EACL,OAAO,OAAO,QAAQA,OAAW,CAAC,CAAC,KAAK,CAAC,WAAW,gBAAgB;EAElE,WAAW,UAAU,WAAW,GAAG,IAC/B,UAAU,QAAQ,iBAAiB,KAAK,IACxC,IAAI,UAAU,QAAQ,iBAAiB,KAAK;EAGhD,WAAW,OAAO,YAChB,OAAO,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,QAAQ,aAAa;GAInD,OAAO,CAAC,QAHkB,SAAS,WAAW,GAAG,IAC7C,QAAQ,QAAQ,iBAAiB,KAAK,IACtC,KAAK,WAAW,GAAE,CAAE,QAAQ,iBAAiB,KAAK,GACrB;EACnC,CAAC,CACH;CACF,EAAE,EACJ;AACF;;;;;;;;;AAUA,MAAM,kBAAkB,YAAoB;CAC1C,MAAM,cAAc,QACjB,QAAQ,OAAO,KAAK,CAAC,CACrB,QAAQ,0BAA0B,cAAc,CAAC,CACjD,QAAQ,0BAA0B,mBAAmB,CAAC,CACtD,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,oBAAoB,WAAW,CAAC,CACxC,QAAQ,oBAAoB,MAAM,CAAC,CACnC,QAAQ,kBAAkB,WAAW;CAExC,OAAO,IAAI,OAAO,IAAI,YAAY,EAAE;AACtC;;;;AAKA,MAAM,YAAY,SAAiB,WAAqB;CACtD,IAAI,QAAQ;CACZ,OACE,QACG,QAAQ,8BAA8B,OAAO,YAAY,EAAE,CAAC,CAC5D,QAAQ,QAAQ,GAAG,CAAC,CACpB,QAAQ,OAAO,EAAE,KAAK;AAE7B;;;;AAKA,MAAM,iBAAiB,KAAa,YAAqC;CACvE,MAAM,QAAQ,eAAe,OAAO;CACpC,MAAM,QAAQ,IAAI,MAAM,KAAK;CAC7B,OAAO,QAAQ,MAAM,MAAM,CAAC,IAAI;AAClC;;;;;AAMA,MAAa,oBAIX,eACA,QACA,iBACW;CACX,IACE,CAAC,gBACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;CAET,KAAK,MAAM,QAAQ,aAAa,OAAO;EACrC,MAAM,EAAE,WAAW,cAAc;EACjC,MAAM,iBAAiB,SAAS,CAAC,MAAM,IAAI,OAAO,KAAK,SAAS;EAEhE,KAAK,MAAM,OAAO,gBAAgB;GAChC,MAAM,mBAAmB,UAAU;GAEnC,IAAI,CAAC,kBAAkB;GAEvB,MAAM,SAAS,cAAc,eAAe,gBAAgB;GAE5D,IAAI,QACF,OAAO,SAAS,WAAW,MAAM;EAErC;CACF;CAEA,OAAO;AACT;;;;;;;;;;;;;;;AAgBA,MAAa,wBAIX,eACA,QACA,iBACuC;CACvC,IACE,CAAC,gBACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;CAEnD,KAAK,MAAM,QAAQ,aAAa,OAAO;EACrC,MAAM,EAAE,WAAW,cAAc;EAGjC,MAAM,SAAS,cAAc,eAAe,SAAS;EAErD,IAAI,QAAQ;GAEV,MAAM,gBAAgB,UADD,UAAUC,4CAAqB;GAGpD,IAAI,eACF,OAAO;IACL,MAAM,SAAS,eAAe,MAAM;IACpC,aAAa;GACf;EAEJ;CACF;CAEA,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;AACnD;;;;;AAMA,MAAa,mBAIX,eACA,WAC+B;CAC/B,MAAM,uBAAuB,cAAc,WAAW,GAAG,IACrD,gBACA,IAAI;CAER,IACE,qBAAqB,WAAW,IAAI,OAAO,EAAE,KAC7C,yBAAyB,IAAI,UAE7B,OAAO;CAGT,OAAO,IAAI,SACT,yBAAyB,MAAM,KAAK;AAExC;;;;AAKA,MAAa,kBAIX,UACA,QACA,YACuB;CACvB,IACE,QAAQ,IAAI,kCACZ,QAAQ,IAAI,mCAAmC,SAE/C,OAAO;CACT,MAAM,QAAQ,gBAAgB,SAAS,KAAK;CAC5C,IAAI,CAAC,OAAO,OAAO;CAGnB,MAAM,gBAAgB,iBAAiB,UAAU,QAAW,KAAK;CAGjE,MAAM,EAAE,MAAM,eAAe,gBAAgB,qBAC3C,eACA,QACA,KACF;CAEA,IAAI,eAAe,kBAAkB,UACnC,OAAO;AAIX"}
1
+ {"version":3,"file":"rewriteUtils.cjs","names":["extractParams","internationalization","fillPath","getRewriteRules","getCanonicalPath"],"sources":["../../../src/localization/rewriteUtils.ts"],"sourcesContent":["import { internationalization } from '@intlayer/config/built';\nimport type { RewriteRules, RoutingConfig } from '@intlayer/types/config';\nimport type {\n LocalesValues,\n ResolvedDefaultLocale,\n} from '@intlayer/types/module_augmentation';\nimport { getCanonicalPath } from './getCanonicalPath';\nimport { extractParams, fillPath, getRewriteRules } from './rewriteMatch';\n\n/**\n * Outcome of resolving a canonical path against the rewrite rules.\n *\n * Discriminated on `isRewritten`: when no rule matched, `path` is the very\n * input that was passed in, so a literal input keeps its literal type. Only a\n * rewritten path is computed at runtime and therefore widens to `string`.\n */\nexport type LocalizedPathResult<CanonicalPath extends string = string> =\n | { path: CanonicalPath; isRewritten: false }\n | { path: string; isRewritten: true };\n\n/** Adds the leading slash a path may be missing. */\ntype WithLeadingSlash<Path extends string> = Path extends `/${string}`\n ? Path\n : `/${Path}`;\n\n/**\n * Computes the locale-prefixed internal path for a path and a locale, mirroring\n * `getInternalPath`'s runtime behaviour: an already-prefixed path is returned\n * untouched, the root collapses to `/${Locale}` (never a trailing slash), and\n * anything else gets the prefix prepended.\n *\n * Falls back to `string` for a non-literal path, where the prefixed and\n * already-prefixed cases cannot be told apart.\n *\n * @example\n * type A = InternalPath<'/about', 'fr'>; // '/fr/about'\n * type B = InternalPath<'/', 'fr'>; // '/fr'\n * type C = InternalPath<'/fr/about', 'fr'>; // '/fr/about' (already prefixed)\n */\nexport type InternalPath<\n Path extends string,\n Locale extends string,\n> = string extends Path\n ? string\n : WithLeadingSlash<Path> extends infer Prefixed extends string\n ? Prefixed extends `/${Locale}` | `/${Locale}/${string}`\n ? Prefixed\n : Prefixed extends '/'\n ? `/${Locale}`\n : `/${Locale}${Prefixed}`\n : never;\n\n/**\n * Given a canonical path (e.g., \"/products/123\"), finds the localized URL pattern\n * (e.g., \"/produits/123\") and reports whether a rule actually matched.\n *\n * Takes already-normalized rules, so callers that resolve the rules once (proxies,\n * static emitters) can reuse them. {@link getLocalizedPath} is the user-facing\n * counterpart: it accepts the raw `routing.rewrite` configuration, defaults to the\n * project configuration, and returns the path alone.\n *\n * @param canonicalPath - The internal application path (e.g. `/product/:id`, `/about`).\n * @param locale - The target locale. Defaults to the configured default locale.\n * @param rewriteRules - Normalized rules, as returned by {@link getRewriteRules}.\n * @returns The localized path, discriminated on whether a rewrite rule matched.\n */\nexport const resolveLocalizedPath = <\n const CanonicalPath extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n canonicalPath: CanonicalPath,\n locale?: Locale,\n rewriteRules?: RewriteRules\n): LocalizedPathResult<CanonicalPath> => {\n if (\n !rewriteRules ||\n (process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false')\n )\n return { path: canonicalPath, isRewritten: false };\n\n for (const rule of rewriteRules.rules) {\n const { canonical, localized } = rule;\n\n // Check if the input path matches a configured canonical pattern\n const params = extractParams(canonicalPath, canonical);\n\n if (params) {\n const targetLocale = locale ?? internationalization.defaultLocale;\n const targetPattern = localized[targetLocale as keyof typeof localized];\n\n if (targetPattern) {\n return {\n path: fillPath(targetPattern, params),\n isRewritten: true,\n };\n }\n }\n }\n\n return { path: canonicalPath, isRewritten: false };\n};\n\n/**\n * Returns the internal path for a given canonical path and locale.\n * Ensures the locale prefix is present exactly once.\n */\nexport const getInternalPath = <\n const Path extends string,\n const Locale extends LocalesValues,\n>(\n canonicalPath: Path,\n locale: Locale\n): InternalPath<Path, Locale> => {\n const pathWithLeadingSlash = canonicalPath.startsWith('/')\n ? canonicalPath\n : `/${canonicalPath}`;\n\n if (\n pathWithLeadingSlash.startsWith(`/${locale}/`) ||\n pathWithLeadingSlash === `/${locale}`\n ) {\n return pathWithLeadingSlash as InternalPath<Path, Locale>;\n }\n\n return `/${locale}${\n pathWithLeadingSlash === '/' ? '' : pathWithLeadingSlash\n }` as InternalPath<Path, Locale>;\n};\n\n/**\n * Given a current pathname and locale, returns the pretty localized path if a rewrite rule exists and the path is not already localized.\n */\nexport const getRewritePath = <\n const Path extends string,\n const Locale extends LocalesValues = ResolvedDefaultLocale,\n>(\n pathname: Path,\n locale: Locale,\n rewrite?: RoutingConfig['rewrite']\n): string | undefined => {\n if (\n process.env.INTLAYER_ROUTING_REWRITE_RULES &&\n process.env.INTLAYER_ROUTING_REWRITE_RULES === 'false'\n )\n return undefined;\n const rules = getRewriteRules(rewrite, 'url');\n if (!rules) return undefined;\n\n // Identify canonical path (relative to root, no locale prefix expected in 'url' context)\n const canonicalPath = getCanonicalPath(pathname, undefined, rules);\n\n // Get the localized path for the current locale\n const { path: localizedPath, isRewritten } = resolveLocalizedPath(\n canonicalPath,\n locale,\n rules\n );\n\n if (isRewritten && localizedPath !== pathname) {\n return localizedPath;\n }\n\n return undefined;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAkEA,MAAa,wBAIX,eACA,QACA,iBACuC;CACvC,IACE,CAAC,gBACA,QAAQ,IAAI,kCACX,QAAQ,IAAI,mCAAmC,SAEjD,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;CAEnD,KAAK,MAAM,QAAQ,aAAa,OAAO;EACrC,MAAM,EAAE,WAAW,cAAc;EAGjC,MAAM,SAASA,gDAAc,eAAe,SAAS;EAErD,IAAI,QAAQ;GAEV,MAAM,gBAAgB,UADD,UAAUC,4CAAqB;GAGpD,IAAI,eACF,OAAO;IACL,MAAMC,2CAAS,eAAe,MAAM;IACpC,aAAa;GACf;EAEJ;CACF;CAEA,OAAO;EAAE,MAAM;EAAe,aAAa;CAAM;AACnD;;;;;AAMA,MAAa,mBAIX,eACA,WAC+B;CAC/B,MAAM,uBAAuB,cAAc,WAAW,GAAG,IACrD,gBACA,IAAI;CAER,IACE,qBAAqB,WAAW,IAAI,OAAO,EAAE,KAC7C,yBAAyB,IAAI,UAE7B,OAAO;CAGT,OAAO,IAAI,SACT,yBAAyB,MAAM,KAAK;AAExC;;;;AAKA,MAAa,kBAIX,UACA,QACA,YACuB;CACvB,IACE,QAAQ,IAAI,kCACZ,QAAQ,IAAI,mCAAmC,SAE/C,OAAO;CACT,MAAM,QAAQC,kDAAgB,SAAS,KAAK;CAC5C,IAAI,CAAC,OAAO,OAAO;CAGnB,MAAM,gBAAgBC,uDAAiB,UAAU,QAAW,KAAK;CAGjE,MAAM,EAAE,MAAM,eAAe,gBAAgB,qBAC3C,eACA,QACA,KACF;CAEA,IAAI,eAAe,kBAAkB,UACnC,OAAO;AAIX"}
@@ -38,11 +38,6 @@ let vitest = require("vitest");
38
38
  (0, vitest.expectTypeOf)(require_localization_rewriteUtils.resolveLocalizedPath("/about")).toEqualTypeOf();
39
39
  });
40
40
  });
41
- (0, vitest.describe)("getCanonicalPath", () => {
42
- (0, vitest.it)("should accept an omitted locale (checks every locale)", () => {
43
- (0, vitest.expectTypeOf)(require_localization_rewriteUtils.getCanonicalPath("/a-propos")).toEqualTypeOf();
44
- });
45
- });
46
41
 
47
42
  //#endregion
48
43
  //# sourceMappingURL=rewriteUtils.test-d.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"rewriteUtils.test-d.cjs","names":["describe","getInternalPath","resolveLocalizedPath","getCanonicalPath"],"sources":["../../../src/localization/rewriteUtils.test-d.ts"],"sourcesContent":["import { describe, expectTypeOf, it } from 'vitest';\nimport {\n getCanonicalPath,\n getInternalPath,\n resolveLocalizedPath,\n} from './rewriteUtils';\n\n/**\n * `getInternalPath` is pure string surgery — no rewrite rules involved — so its\n * result is fully derivable from the arguments whenever both are literals.\n */\ndescribe('getInternalPath', () => {\n it('should prefix a literal path with the locale', () => {\n expectTypeOf(getInternalPath('/about', 'fr')).toEqualTypeOf<'/fr/about'>();\n });\n\n it('should collapse the root to a bare prefix, never a trailing slash', () => {\n expectTypeOf(getInternalPath('/', 'fr')).toEqualTypeOf<'/fr'>();\n });\n\n it('should leave an already-prefixed path untouched', () => {\n expectTypeOf(\n getInternalPath('/fr/about', 'fr')\n ).toEqualTypeOf<'/fr/about'>();\n expectTypeOf(getInternalPath('/fr', 'fr')).toEqualTypeOf<'/fr'>();\n });\n\n it('should add the leading slash a path is missing', () => {\n expectTypeOf(getInternalPath('about', 'fr')).toEqualTypeOf<'/fr/about'>();\n });\n\n it('should widen to string when the path is not a literal', () => {\n const dynamicPath = '/about' as string;\n\n expectTypeOf(getInternalPath(dynamicPath, 'fr')).toEqualTypeOf<string>();\n });\n});\n\n/**\n * `resolveLocalizedPath` only computes a new path when a rule matched, so the\n * `isRewritten: false` branch still carries the exact input it was given.\n */\ndescribe('resolveLocalizedPath', () => {\n it('should keep the input literal on the non-rewritten branch', () => {\n const result = resolveLocalizedPath('/about', 'fr');\n\n if (!result.isRewritten) {\n expectTypeOf(result.path).toEqualTypeOf<'/about'>();\n } else {\n expectTypeOf(result.path).toEqualTypeOf<string>();\n }\n });\n\n it('should discriminate on isRewritten', () => {\n expectTypeOf(resolveLocalizedPath('/about')).toEqualTypeOf<\n | { path: '/about'; isRewritten: false }\n | { path: string; isRewritten: true }\n >();\n });\n});\n\ndescribe('getCanonicalPath', () => {\n it('should accept an omitted locale (checks every locale)', () => {\n expectTypeOf(getCanonicalPath('/a-propos')).toEqualTypeOf<string>();\n });\n});\n"],"mappings":";;;;;;;;IAWAA,iBAAS,yBAAyB;CAChC,eAAG,sDAAsD;EACvD,yBAAaC,kDAAgB,UAAU,IAAI,CAAC,CAAC,CAAC,cAA2B;CAC3E,CAAC;CAED,eAAG,2EAA2E;EAC5E,yBAAaA,kDAAgB,KAAK,IAAI,CAAC,CAAC,CAAC,cAAqB;CAChE,CAAC;CAED,eAAG,yDAAyD;EAC1D,yBACEA,kDAAgB,aAAa,IAAI,CACnC,CAAC,CAAC,cAA2B;EAC7B,yBAAaA,kDAAgB,OAAO,IAAI,CAAC,CAAC,CAAC,cAAqB;CAClE,CAAC;CAED,eAAG,wDAAwD;EACzD,yBAAaA,kDAAgB,SAAS,IAAI,CAAC,CAAC,CAAC,cAA2B;CAC1E,CAAC;CAED,eAAG,+DAA+D;EAGhE,yBAAaA,kDAAgB,UAAa,IAAI,CAAC,CAAC,CAAC,cAAsB;CACzE,CAAC;AACH,CAAC;;;;;IAMDD,iBAAS,8BAA8B;CACrC,eAAG,mEAAmE;EACpE,MAAM,SAASE,uDAAqB,UAAU,IAAI;EAElD,IAAI,CAAC,OAAO,aACV,yBAAa,OAAO,IAAI,CAAC,CAAC,cAAwB;OAElD,yBAAa,OAAO,IAAI,CAAC,CAAC,cAAsB;CAEpD,CAAC;CAED,eAAG,4CAA4C;EAC7C,yBAAaA,uDAAqB,QAAQ,CAAC,CAAC,CAAC,cAG3C;CACJ,CAAC;AACH,CAAC;IAEDF,iBAAS,0BAA0B;CACjC,eAAG,+DAA+D;EAChE,yBAAaG,mDAAiB,WAAW,CAAC,CAAC,CAAC,cAAsB;CACpE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"rewriteUtils.test-d.cjs","names":["describe","getInternalPath","resolveLocalizedPath"],"sources":["../../../src/localization/rewriteUtils.test-d.ts"],"sourcesContent":["import { describe, expectTypeOf, it } from 'vitest';\nimport { getInternalPath, resolveLocalizedPath } from './rewriteUtils';\n\n/**\n * `getInternalPath` is pure string surgery — no rewrite rules involved — so its\n * result is fully derivable from the arguments whenever both are literals.\n */\ndescribe('getInternalPath', () => {\n it('should prefix a literal path with the locale', () => {\n expectTypeOf(getInternalPath('/about', 'fr')).toEqualTypeOf<'/fr/about'>();\n });\n\n it('should collapse the root to a bare prefix, never a trailing slash', () => {\n expectTypeOf(getInternalPath('/', 'fr')).toEqualTypeOf<'/fr'>();\n });\n\n it('should leave an already-prefixed path untouched', () => {\n expectTypeOf(\n getInternalPath('/fr/about', 'fr')\n ).toEqualTypeOf<'/fr/about'>();\n expectTypeOf(getInternalPath('/fr', 'fr')).toEqualTypeOf<'/fr'>();\n });\n\n it('should add the leading slash a path is missing', () => {\n expectTypeOf(getInternalPath('about', 'fr')).toEqualTypeOf<'/fr/about'>();\n });\n\n it('should widen to string when the path is not a literal', () => {\n const dynamicPath = '/about' as string;\n\n expectTypeOf(getInternalPath(dynamicPath, 'fr')).toEqualTypeOf<string>();\n });\n});\n\n/**\n * `resolveLocalizedPath` only computes a new path when a rule matched, so the\n * `isRewritten: false` branch still carries the exact input it was given.\n */\ndescribe('resolveLocalizedPath', () => {\n it('should keep the input literal on the non-rewritten branch', () => {\n const result = resolveLocalizedPath('/about', 'fr');\n\n if (!result.isRewritten) {\n expectTypeOf(result.path).toEqualTypeOf<'/about'>();\n } else {\n expectTypeOf(result.path).toEqualTypeOf<string>();\n }\n });\n\n it('should discriminate on isRewritten', () => {\n expectTypeOf(resolveLocalizedPath('/about')).toEqualTypeOf<\n | { path: '/about'; isRewritten: false }\n | { path: string; isRewritten: true }\n >();\n });\n});\n"],"mappings":";;;;;;;;IAOAA,iBAAS,yBAAyB;CAChC,eAAG,sDAAsD;EACvD,yBAAaC,kDAAgB,UAAU,IAAI,CAAC,CAAC,CAAC,cAA2B;CAC3E,CAAC;CAED,eAAG,2EAA2E;EAC5E,yBAAaA,kDAAgB,KAAK,IAAI,CAAC,CAAC,CAAC,cAAqB;CAChE,CAAC;CAED,eAAG,yDAAyD;EAC1D,yBACEA,kDAAgB,aAAa,IAAI,CACnC,CAAC,CAAC,cAA2B;EAC7B,yBAAaA,kDAAgB,OAAO,IAAI,CAAC,CAAC,CAAC,cAAqB;CAClE,CAAC;CAED,eAAG,wDAAwD;EACzD,yBAAaA,kDAAgB,SAAS,IAAI,CAAC,CAAC,CAAC,cAA2B;CAC1E,CAAC;CAED,eAAG,+DAA+D;EAGhE,yBAAaA,kDAAgB,UAAa,IAAI,CAAC,CAAC,CAAC,cAAsB;CACzE,CAAC;AACH,CAAC;;;;;IAMDD,iBAAS,8BAA8B;CACrC,eAAG,mEAAmE;EACpE,MAAM,SAASE,uDAAqB,UAAU,IAAI;EAElD,IAAI,CAAC,OAAO,aACV,yBAAa,OAAO,IAAI,CAAC,CAAC,cAAwB;OAElD,yBAAa,OAAO,IAAI,CAAC,CAAC,cAAsB;CAEpD,CAAC;CAED,eAAG,4CAA4C;EAC7C,yBAAaA,uDAAqB,QAAQ,CAAC,CAAC,CAAC,cAG3C;CACJ,CAAC;AACH,CAAC"}