@intlayer/engine 9.5.9-canary.0 → 9.5.10

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 (248) hide show
  1. package/dist/cjs/_virtual/_utils_asset.cjs +1 -1
  2. package/dist/cjs/build.cjs +4 -4
  3. package/dist/cjs/buildIntlayerDictionary/writeDynamicDictionary.cjs +2 -2
  4. package/dist/cjs/buildIntlayerDictionary/writeFetchDictionary.cjs +3 -3
  5. package/dist/cjs/buildIntlayerDictionary/writeMergedDictionary.cjs +1 -1
  6. package/dist/cjs/buildIntlayerDictionary/writeNestedDictionary.cjs +3 -3
  7. package/dist/cjs/buildIntlayerDictionary/writeRemoteDictionary.cjs +2 -2
  8. package/dist/cjs/buildIntlayerDictionary/writeUnmergedDictionary.cjs +2 -2
  9. package/dist/cjs/cleanOutputDir.cjs +1 -1
  10. package/dist/cjs/cleanRemovedContentDeclaration.cjs +1 -1
  11. package/dist/cjs/cli.cjs +10 -3
  12. package/dist/cjs/createDictionaryEntryPoint/createDictionaryEntryPoint.cjs +1 -1
  13. package/dist/cjs/createDictionaryEntryPoint/getBuiltDictionariesPath.cjs +2 -2
  14. package/dist/cjs/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.cjs +2 -2
  15. package/dist/cjs/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.cjs +2 -2
  16. package/dist/cjs/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.cjs +2 -2
  17. package/dist/cjs/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.cjs +2 -2
  18. package/dist/cjs/createType/createModuleAugmentation.cjs +3 -3
  19. package/dist/cjs/createType/createType.cjs +1 -1
  20. package/dist/cjs/docReview/index.cjs +5 -5
  21. package/dist/cjs/docReview/pipeline.cjs +4 -4
  22. package/dist/cjs/docReview/reviewReport.cjs.map +1 -1
  23. package/dist/cjs/fetchDistantDictionaries.cjs +1 -1
  24. package/dist/cjs/handleContentDeclarationFileChange.cjs +2 -2
  25. package/dist/cjs/handleUnlinkedContentDeclarationFile.cjs +1 -1
  26. package/dist/cjs/init/cms.cjs +35 -0
  27. package/dist/cjs/init/cms.cjs.map +1 -1
  28. package/dist/cjs/init/documentationRouter.cjs +141 -0
  29. package/dist/cjs/init/documentationRouter.cjs.map +1 -0
  30. package/dist/cjs/init/frameworkSetup/backend/index.cjs +138 -0
  31. package/dist/cjs/init/frameworkSetup/backend/index.cjs.map +1 -0
  32. package/dist/cjs/init/frameworkSetup/backend/transforms.cjs +223 -0
  33. package/dist/cjs/init/frameworkSetup/backend/transforms.cjs.map +1 -0
  34. package/dist/cjs/init/frameworkSetup/index.cjs +9 -3
  35. package/dist/cjs/init/frameworkSetup/index.cjs.map +1 -1
  36. package/dist/cjs/init/frameworkSetup/localeRouting.cjs +13 -0
  37. package/dist/cjs/init/frameworkSetup/localeRouting.cjs.map +1 -0
  38. package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs +34 -7
  39. package/dist/cjs/init/frameworkSetup/nextAppRouter/index.cjs.map +1 -1
  40. package/dist/cjs/init/frameworkSetup/nextAppRouter/restructure.cjs +1 -1
  41. package/dist/cjs/init/frameworkSetup/nextAppRouter/templates.cjs +56 -0
  42. package/dist/cjs/init/frameworkSetup/nextAppRouter/templates.cjs.map +1 -1
  43. package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs +2 -2
  44. package/dist/cjs/init/frameworkSetup/nextAppRouter/transforms.cjs.map +1 -1
  45. package/dist/cjs/init/frameworkSetup/tanstackStart/index.cjs +32 -3
  46. package/dist/cjs/init/frameworkSetup/tanstackStart/index.cjs.map +1 -1
  47. package/dist/cjs/init/frameworkSetup/tanstackStart/restructure.cjs +1 -1
  48. package/dist/cjs/init/frameworkSetup/tanstackStart/templates.cjs +58 -0
  49. package/dist/cjs/init/frameworkSetup/tanstackStart/templates.cjs.map +1 -1
  50. package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs +94 -14
  51. package/dist/cjs/init/frameworkSetup/tanstackStart/transforms.cjs.map +1 -1
  52. package/dist/cjs/init/index.cjs +46 -159
  53. package/dist/cjs/init/index.cjs.map +1 -1
  54. package/dist/cjs/init/utils/configManipulation.cjs +39 -0
  55. package/dist/cjs/init/utils/configManipulation.cjs.map +1 -1
  56. package/dist/cjs/init/utils/fileSystem.cjs +1 -1
  57. package/dist/cjs/init/utils/githubActions.cjs +1 -1
  58. package/dist/cjs/init/utils/index.cjs +10 -0
  59. package/dist/cjs/init/utils/intlayerDependencies.cjs +1 -1
  60. package/dist/cjs/init/utils/lintConfig.cjs +52 -0
  61. package/dist/cjs/init/utils/lintConfig.cjs.map +1 -0
  62. package/dist/cjs/init/utils/packageManager.cjs +63 -14
  63. package/dist/cjs/init/utils/packageManager.cjs.map +1 -1
  64. package/dist/cjs/init/utils/urlRoutingFramework.cjs +41 -0
  65. package/dist/cjs/init/utils/urlRoutingFramework.cjs.map +1 -0
  66. package/dist/cjs/initConfig/index.cjs +5 -2
  67. package/dist/cjs/initConfig/index.cjs.map +1 -1
  68. package/dist/cjs/installLSP.cjs +1 -1
  69. package/dist/cjs/installMCP/installMCP.cjs +1 -1
  70. package/dist/cjs/installSkills/index.cjs +1 -1
  71. package/dist/cjs/listDictionariesPath.cjs +1 -1
  72. package/dist/cjs/listGitFiles.cjs +1 -1
  73. package/dist/cjs/loadDictionaries/getIntlayerBundle.cjs +2 -2
  74. package/dist/cjs/loadDictionaries/index.cjs +1 -1
  75. package/dist/cjs/loadDictionaries/loadContentDeclaration.cjs +2 -2
  76. package/dist/cjs/loadDictionaries/loadDictionaries.cjs +1 -1
  77. package/dist/cjs/loadDictionaries/loadLocalDictionaries.cjs +1 -1
  78. package/dist/cjs/loadDictionaries/loadMarkdownContentDeclaration.cjs +1 -1
  79. package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs +104 -43
  80. package/dist/cjs/loadDictionaries/logTypeScriptErrors.cjs.map +1 -1
  81. package/dist/cjs/logConfigDetails.cjs +1 -1
  82. package/dist/cjs/prepareIntlayer.cjs +4 -4
  83. package/dist/cjs/scan/index.cjs +1 -1
  84. package/dist/cjs/scan/scanWebsite.cjs +1 -1
  85. package/dist/cjs/syncPluginKit/createFileAdapter.cjs +1 -1
  86. package/dist/cjs/syncPluginKit/index.cjs +1 -1
  87. package/dist/cjs/utils/buildComponentFilesList.cjs +1 -1
  88. package/dist/cjs/utils/contentWatcherLock.cjs +2 -2
  89. package/dist/cjs/utils/index.cjs +4 -4
  90. package/dist/cjs/utils/readDictionariesFromDisk.cjs +1 -1
  91. package/dist/cjs/utils/runOnce.cjs +1 -1
  92. package/dist/cjs/utils/runParallel/pidTree.cjs +1 -1
  93. package/dist/cjs/utils/withFileLock.cjs +1 -1
  94. package/dist/cjs/watcher.cjs +6 -6
  95. package/dist/cjs/writeConfiguration/index.cjs +1 -1
  96. package/dist/cjs/writeContentDeclaration/processContentDeclarationContent.cjs +2 -2
  97. package/dist/cjs/writeContentDeclaration/transformJSFile.cjs +1 -1
  98. package/dist/cjs/writeContentDeclaration/writeContentDeclaration.cjs +4 -4
  99. package/dist/cjs/writeContentDeclaration/writeJSFile.cjs +3 -3
  100. package/dist/cjs/writeContentDeclaration/writeMarkdownFile.cjs +1 -1
  101. package/dist/cjs/writeContentDeclaration/writeYamlFile.cjs +1 -1
  102. package/dist/cjs/writeFileIfChanged.cjs +1 -1
  103. package/dist/esm/_virtual/_utils_asset.mjs +1 -1
  104. package/dist/esm/build.mjs +4 -4
  105. package/dist/esm/buildIntlayerDictionary/writeDynamicDictionary.mjs +2 -2
  106. package/dist/esm/buildIntlayerDictionary/writeFetchDictionary.mjs +3 -3
  107. package/dist/esm/buildIntlayerDictionary/writeMergedDictionary.mjs +1 -1
  108. package/dist/esm/buildIntlayerDictionary/writeNestedDictionary.mjs +3 -3
  109. package/dist/esm/buildIntlayerDictionary/writeRemoteDictionary.mjs +2 -2
  110. package/dist/esm/buildIntlayerDictionary/writeUnmergedDictionary.mjs +2 -2
  111. package/dist/esm/cleanOutputDir.mjs +1 -1
  112. package/dist/esm/cleanRemovedContentDeclaration.mjs +1 -1
  113. package/dist/esm/cli.mjs +8 -6
  114. package/dist/esm/createDictionaryEntryPoint/createDictionaryEntryPoint.mjs +1 -1
  115. package/dist/esm/createDictionaryEntryPoint/getBuiltDictionariesPath.mjs +2 -2
  116. package/dist/esm/createDictionaryEntryPoint/getBuiltDynamicDictionariesPath.mjs +2 -2
  117. package/dist/esm/createDictionaryEntryPoint/getBuiltFetchDictionariesPath.mjs +2 -2
  118. package/dist/esm/createDictionaryEntryPoint/getBuiltRemoteDictionariesPath.mjs +2 -2
  119. package/dist/esm/createDictionaryEntryPoint/getBuiltUnmergedDictionariesPath.mjs +2 -2
  120. package/dist/esm/createType/createModuleAugmentation.mjs +3 -3
  121. package/dist/esm/createType/createType.mjs +1 -1
  122. package/dist/esm/docReview/index.mjs +5 -5
  123. package/dist/esm/docReview/pipeline.mjs +4 -4
  124. package/dist/esm/docReview/reviewReport.mjs.map +1 -1
  125. package/dist/esm/fetchDistantDictionaries.mjs +1 -1
  126. package/dist/esm/handleContentDeclarationFileChange.mjs +2 -2
  127. package/dist/esm/handleUnlinkedContentDeclarationFile.mjs +1 -1
  128. package/dist/esm/init/cms.mjs +35 -2
  129. package/dist/esm/init/cms.mjs.map +1 -1
  130. package/dist/esm/init/documentationRouter.mjs +139 -0
  131. package/dist/esm/init/documentationRouter.mjs.map +1 -0
  132. package/dist/esm/init/frameworkSetup/backend/index.mjs +130 -0
  133. package/dist/esm/init/frameworkSetup/backend/index.mjs.map +1 -0
  134. package/dist/esm/init/frameworkSetup/backend/transforms.mjs +216 -0
  135. package/dist/esm/init/frameworkSetup/backend/transforms.mjs.map +1 -0
  136. package/dist/esm/init/frameworkSetup/index.mjs +9 -3
  137. package/dist/esm/init/frameworkSetup/index.mjs.map +1 -1
  138. package/dist/esm/init/frameworkSetup/localeRouting.mjs +12 -0
  139. package/dist/esm/init/frameworkSetup/localeRouting.mjs.map +1 -0
  140. package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs +36 -9
  141. package/dist/esm/init/frameworkSetup/nextAppRouter/index.mjs.map +1 -1
  142. package/dist/esm/init/frameworkSetup/nextAppRouter/restructure.mjs +1 -1
  143. package/dist/esm/init/frameworkSetup/nextAppRouter/templates.mjs +54 -1
  144. package/dist/esm/init/frameworkSetup/nextAppRouter/templates.mjs.map +1 -1
  145. package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs +2 -2
  146. package/dist/esm/init/frameworkSetup/nextAppRouter/transforms.mjs.map +1 -1
  147. package/dist/esm/init/frameworkSetup/tanstackStart/index.mjs +35 -6
  148. package/dist/esm/init/frameworkSetup/tanstackStart/index.mjs.map +1 -1
  149. package/dist/esm/init/frameworkSetup/tanstackStart/restructure.mjs +1 -1
  150. package/dist/esm/init/frameworkSetup/tanstackStart/templates.mjs +56 -1
  151. package/dist/esm/init/frameworkSetup/tanstackStart/templates.mjs.map +1 -1
  152. package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs +94 -15
  153. package/dist/esm/init/frameworkSetup/tanstackStart/transforms.mjs.map +1 -1
  154. package/dist/esm/init/index.mjs +42 -158
  155. package/dist/esm/init/index.mjs.map +1 -1
  156. package/dist/esm/init/utils/configManipulation.mjs +38 -1
  157. package/dist/esm/init/utils/configManipulation.mjs.map +1 -1
  158. package/dist/esm/init/utils/fileSystem.mjs +1 -1
  159. package/dist/esm/init/utils/githubActions.mjs +1 -1
  160. package/dist/esm/init/utils/index.mjs +5 -3
  161. package/dist/esm/init/utils/intlayerDependencies.mjs +1 -1
  162. package/dist/esm/init/utils/lintConfig.mjs +50 -0
  163. package/dist/esm/init/utils/lintConfig.mjs.map +1 -0
  164. package/dist/esm/init/utils/packageManager.mjs +61 -15
  165. package/dist/esm/init/utils/packageManager.mjs.map +1 -1
  166. package/dist/esm/init/utils/urlRoutingFramework.mjs +40 -0
  167. package/dist/esm/init/utils/urlRoutingFramework.mjs.map +1 -0
  168. package/dist/esm/initConfig/index.mjs +5 -2
  169. package/dist/esm/initConfig/index.mjs.map +1 -1
  170. package/dist/esm/installLSP.mjs +1 -1
  171. package/dist/esm/installMCP/installMCP.mjs +1 -1
  172. package/dist/esm/installSkills/index.mjs +1 -1
  173. package/dist/esm/listDictionariesPath.mjs +1 -1
  174. package/dist/esm/listGitFiles.mjs +1 -1
  175. package/dist/esm/loadDictionaries/getIntlayerBundle.mjs +2 -2
  176. package/dist/esm/loadDictionaries/index.mjs +1 -1
  177. package/dist/esm/loadDictionaries/loadContentDeclaration.mjs +2 -2
  178. package/dist/esm/loadDictionaries/loadDictionaries.mjs +1 -1
  179. package/dist/esm/loadDictionaries/loadLocalDictionaries.mjs +1 -1
  180. package/dist/esm/loadDictionaries/loadMarkdownContentDeclaration.mjs +1 -1
  181. package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs +105 -44
  182. package/dist/esm/loadDictionaries/logTypeScriptErrors.mjs.map +1 -1
  183. package/dist/esm/logConfigDetails.mjs +1 -1
  184. package/dist/esm/prepareIntlayer.mjs +4 -4
  185. package/dist/esm/scan/index.mjs +1 -1
  186. package/dist/esm/scan/scanWebsite.mjs +1 -1
  187. package/dist/esm/syncPluginKit/createFileAdapter.mjs +1 -1
  188. package/dist/esm/syncPluginKit/index.mjs +1 -1
  189. package/dist/esm/utils/buildComponentFilesList.mjs +1 -1
  190. package/dist/esm/utils/contentWatcherLock.mjs +2 -2
  191. package/dist/esm/utils/index.mjs +4 -4
  192. package/dist/esm/utils/readDictionariesFromDisk.mjs +1 -1
  193. package/dist/esm/utils/runOnce.mjs +1 -1
  194. package/dist/esm/utils/runParallel/pidTree.mjs +1 -1
  195. package/dist/esm/utils/withFileLock.mjs +1 -1
  196. package/dist/esm/watcher.mjs +6 -6
  197. package/dist/esm/writeConfiguration/index.mjs +1 -1
  198. package/dist/esm/writeContentDeclaration/processContentDeclarationContent.mjs +2 -2
  199. package/dist/esm/writeContentDeclaration/transformJSFile.mjs +1 -1
  200. package/dist/esm/writeContentDeclaration/writeContentDeclaration.mjs +4 -4
  201. package/dist/esm/writeContentDeclaration/writeJSFile.mjs +3 -3
  202. package/dist/esm/writeContentDeclaration/writeMarkdownFile.mjs +1 -1
  203. package/dist/esm/writeContentDeclaration/writeYamlFile.mjs +1 -1
  204. package/dist/esm/writeFileIfChanged.mjs +1 -1
  205. package/dist/types/cli.d.ts +5 -3
  206. package/dist/types/docReview/reviewReport.d.ts.map +1 -1
  207. package/dist/types/formatDictionary.d.ts +2 -2
  208. package/dist/types/init/cms.d.ts +11 -0
  209. package/dist/types/init/cms.d.ts.map +1 -1
  210. package/dist/types/init/documentationRouter.d.ts +64 -0
  211. package/dist/types/init/documentationRouter.d.ts.map +1 -0
  212. package/dist/types/init/frameworkSetup/backend/index.d.ts +16 -0
  213. package/dist/types/init/frameworkSetup/backend/index.d.ts.map +1 -0
  214. package/dist/types/init/frameworkSetup/backend/transforms.d.ts +37 -0
  215. package/dist/types/init/frameworkSetup/backend/transforms.d.ts.map +1 -0
  216. package/dist/types/init/frameworkSetup/index.d.ts.map +1 -1
  217. package/dist/types/init/frameworkSetup/localeRouting.d.ts +11 -0
  218. package/dist/types/init/frameworkSetup/localeRouting.d.ts.map +1 -0
  219. package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts +5 -5
  220. package/dist/types/init/frameworkSetup/nextAppRouter/index.d.ts.map +1 -1
  221. package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts +12 -0
  222. package/dist/types/init/frameworkSetup/nextAppRouter/templates.d.ts.map +1 -1
  223. package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts +10 -1
  224. package/dist/types/init/frameworkSetup/nextAppRouter/transforms.d.ts.map +1 -1
  225. package/dist/types/init/frameworkSetup/tanstackStart/index.d.ts +3 -2
  226. package/dist/types/init/frameworkSetup/tanstackStart/index.d.ts.map +1 -1
  227. package/dist/types/init/frameworkSetup/tanstackStart/templates.d.ts +10 -0
  228. package/dist/types/init/frameworkSetup/tanstackStart/templates.d.ts.map +1 -1
  229. package/dist/types/init/frameworkSetup/tanstackStart/transforms.d.ts +12 -0
  230. package/dist/types/init/frameworkSetup/tanstackStart/transforms.d.ts.map +1 -1
  231. package/dist/types/init/frameworkSetup/types.d.ts +6 -0
  232. package/dist/types/init/frameworkSetup/types.d.ts.map +1 -1
  233. package/dist/types/init/index.d.ts +15 -1
  234. package/dist/types/init/index.d.ts.map +1 -1
  235. package/dist/types/init/utils/configManipulation.d.ts +14 -0
  236. package/dist/types/init/utils/configManipulation.d.ts.map +1 -1
  237. package/dist/types/init/utils/index.d.ts +5 -3
  238. package/dist/types/init/utils/lintConfig.d.ts +28 -0
  239. package/dist/types/init/utils/lintConfig.d.ts.map +1 -0
  240. package/dist/types/init/utils/packageManager.d.ts +29 -6
  241. package/dist/types/init/utils/packageManager.d.ts.map +1 -1
  242. package/dist/types/init/utils/urlRoutingFramework.d.ts +9 -0
  243. package/dist/types/init/utils/urlRoutingFramework.d.ts.map +1 -0
  244. package/dist/types/initConfig/index.d.ts +3 -1
  245. package/dist/types/initConfig/index.d.ts.map +1 -1
  246. package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts +4 -0
  247. package/dist/types/loadDictionaries/logTypeScriptErrors.d.ts.map +1 -1
  248. package/package.json +8 -8
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_runtime = require('../../../_virtual/_rolldown/runtime.cjs');
3
3
  const require_utils_babelParser = require('../../../utils/babelParser.cjs');
4
4
  const require_init_utils_astImports = require('../../utils/astImports.cjs');
5
+ const require_init_frameworkSetup_tanstackStart_templates = require('./templates.cjs');
5
6
  let recast = require("recast");
6
7
  recast = require_runtime.__toESM(recast);
7
8
 
@@ -125,6 +126,97 @@ const setHtmlLangAndDir = (ast) => {
125
126
  } });
126
127
  };
127
128
  /**
129
+ * Wraps the first `{children}` expression inside `funcNode` with
130
+ * `<IntlayerProvider locale={locale}>`. Returns whether a wrap happened.
131
+ */
132
+ const wrapChildrenWithProvider = (funcNode) => {
133
+ let wrapped = false;
134
+ recast.visit(funcNode, { visitJSXExpressionContainer(path) {
135
+ if (wrapped) return false;
136
+ const expression = path.node.expression;
137
+ if (expression?.type === "Identifier" && expression.name === "children") {
138
+ const providerElement = parseTsx("const __wrap = <IntlayerProvider locale={locale}>{__child__}</IntlayerProvider>;").program.body[0].declarations[0].init;
139
+ providerElement.children = [path.node];
140
+ path.replace(providerElement);
141
+ wrapped = true;
142
+ return false;
143
+ }
144
+ this.traverse(path);
145
+ } });
146
+ return wrapped;
147
+ };
148
+ /** Whether `funcNode` already binds `locale` in its body or parameters. */
149
+ const bindsLocale = (funcNode) => funcNode.body?.type === "BlockStatement" && funcNode.body.body.some((stmt) => stmt.type === "VariableDeclaration" && stmt.declarations.some((d) => patternBindsName(d.id, "locale"))) || (funcNode.params ?? []).some((param) => patternBindsName(param, "locale"));
150
+ /**
151
+ * Finds the options object of the root route declaration —
152
+ * `createRootRoute({…})` or `createRootRouteWithContext<…>()({…})`. Returns
153
+ * `null` when absent or not an object literal.
154
+ */
155
+ const findRootRouteOptions = (ast) => {
156
+ let options = null;
157
+ recast.visit(ast, { visitCallExpression(path) {
158
+ const { callee, arguments: args } = path.node;
159
+ const isCreateRootRoute = callee.type === "Identifier" && callee.name === "createRootRoute";
160
+ const isCreateRootRouteWithContext = callee.type === "CallExpression" && callee.callee?.type === "Identifier" && callee.callee.name === "createRootRouteWithContext";
161
+ if ((isCreateRootRoute || isCreateRootRouteWithContext) && args[0]?.type === "ObjectExpression") {
162
+ options = args[0];
163
+ return false;
164
+ }
165
+ this.traverse(path);
166
+ } });
167
+ return options;
168
+ };
169
+ /** Module-scope identifier of the injected request-locale server function. */
170
+ const REQUEST_LOCALE_FUNCTION_NAME = "getRequestLocale";
171
+ /**
172
+ * Wraps the `{children}` of a TanStack Start root document with
173
+ * `IntlayerProvider` for routing modes without a locale path segment. The
174
+ * locale is resolved per request by a server function exposed through the root
175
+ * `loader`, and read with `Route.useLoaderData()`. Safe and idempotent: bails
176
+ * when the provider is already present, when no `<html>` document or
177
+ * `{children}` is found, or when the root route cannot safely take a loader
178
+ * (no `Route` binding, no options object, or an existing `loader`).
179
+ *
180
+ * @param code Source of the project's `__root` document.
181
+ */
182
+ const wrapRootWithRequestLocaleProvider = (code) => {
183
+ if (code.includes("IntlayerProvider")) return {
184
+ code,
185
+ status: "already"
186
+ };
187
+ const ast = parseTsx(code);
188
+ const funcNode = findHtmlDocumentFunction(ast);
189
+ const rootRouteOptions = findRootRouteOptions(ast);
190
+ const hasLoader = rootRouteOptions?.properties.some((property) => (property.key?.name ?? property.key?.value) === "loader");
191
+ if (!funcNode || !rootRouteOptions || hasLoader || !require_init_utils_astImports.isModuleScopeBinding(ast, "Route")) return {
192
+ code,
193
+ status: "skipped"
194
+ };
195
+ if (!wrapChildrenWithProvider(funcNode)) return {
196
+ code,
197
+ status: "skipped"
198
+ };
199
+ if (!bindsLocale(funcNode)) {
200
+ if (funcNode.body?.type !== "BlockStatement") funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);
201
+ funcNode.body.body.unshift(parseTsx("const locale = Route.useLoaderData();").program.body[0]);
202
+ }
203
+ rootRouteOptions.properties.unshift(b.property("init", b.identifier("loader"), b.arrowFunctionExpression([], b.callExpression(b.identifier(REQUEST_LOCALE_FUNCTION_NAME), []))));
204
+ const insertsServerFunction = !require_init_utils_astImports.isModuleScopeBinding(ast, REQUEST_LOCALE_FUNCTION_NAME);
205
+ if (insertsServerFunction) ast.program.body.splice(require_init_utils_astImports.firstInsertIndex(ast), 0, parseTsx(require_init_frameworkSetup_tanstackStart_templates.REQUEST_LOCALE_SERVER_FUNCTION).program.body[0]);
206
+ require_init_utils_astImports.ensureNamedImport(ast, "IntlayerProvider", "react-intlayer");
207
+ require_init_utils_astImports.ensureNamedImport(ast, "createServerFn", "@tanstack/react-start");
208
+ require_init_utils_astImports.ensureNamedImport(ast, "getRequestHeader", "@tanstack/react-start/server");
209
+ require_init_utils_astImports.ensureNamedImport(ast, "getCookie", "intlayer");
210
+ require_init_utils_astImports.ensureNamedImport(ast, "getLocale", "intlayer");
211
+ require_init_utils_astImports.ensureNamedImport(ast, "getHTMLTextDir", "intlayer");
212
+ setHtmlLangAndDir(ast);
213
+ const printedCode = recast.print(ast).code;
214
+ return {
215
+ code: insertsServerFunction ? printedCode.replace(new RegExp(`([^\\n])\\n(const ${REQUEST_LOCALE_FUNCTION_NAME} = )`), "$1\n\n$2") : printedCode,
216
+ status: "wrapped"
217
+ };
218
+ };
219
+ /**
128
220
  * Wraps the `{children}` of a TanStack Start root document with
129
221
  * `IntlayerProvider`, deriving the locale from the locale segment route params.
130
222
  * Safe and idempotent: bails (returns the original code) when the provider is
@@ -146,20 +238,7 @@ const wrapRootWithProvider = (code, localeSegment) => {
146
238
  code,
147
239
  status: "skipped"
148
240
  };
149
- let wrapped = false;
150
- recast.visit(funcNode, { visitJSXExpressionContainer(path) {
151
- if (wrapped) return false;
152
- const expression = path.node.expression;
153
- if (expression?.type === "Identifier" && expression.name === "children") {
154
- const providerElement = parseTsx("const __wrap = <IntlayerProvider locale={locale}>{__child__}</IntlayerProvider>;").program.body[0].declarations[0].init;
155
- providerElement.children = [path.node];
156
- path.replace(providerElement);
157
- wrapped = true;
158
- return false;
159
- }
160
- this.traverse(path);
161
- } });
162
- if (!wrapped) return {
241
+ if (!wrapChildrenWithProvider(funcNode)) return {
163
242
  code,
164
243
  status: "skipped"
165
244
  };
@@ -182,4 +261,5 @@ const wrapRootWithProvider = (code, localeSegment) => {
182
261
 
183
262
  //#endregion
184
263
  exports.wrapRootWithProvider = wrapRootWithProvider;
264
+ exports.wrapRootWithRequestLocaleProvider = wrapRootWithRequestLocaleProvider;
185
265
  //# sourceMappingURL=transforms.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"transforms.cjs","names":["babelTsParser","isModuleScopeBinding","firstInsertIndex"],"sources":["../../../../../src/init/frameworkSetup/tanstackStart/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/babelParser';\nimport {\n ensureNamedImport,\n firstInsertIndex,\n isModuleScopeBinding,\n} from '../../utils/astImports';\n\nconst { builders: b, namedTypes: n } = recast.types;\n\n/** Module-scope identifier bound to the locale route's typed API. */\nconst LOCALE_ROUTE_API_VARIABLE = 'localeRoute';\n\n/** babel-ts parser handles TypeScript *and* JSX. */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: babelTsParser });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped';\n};\n\n/**\n * Finds the single function that returns the `<html>` document element. Returns\n * `null` when there is no such function, or more than one (ambiguous).\n */\nconst findHtmlDocumentFunction = (ast: any): any => {\n const found = new Set<any>();\n\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n // Walk up to the nearest enclosing function node.\n let current = path.parentPath;\n while (current) {\n const value = current.value;\n if (\n value &&\n (n.FunctionDeclaration.check(value) ||\n n.FunctionExpression.check(value) ||\n n.ArrowFunctionExpression.check(value))\n ) {\n found.add(value);\n break;\n }\n current = current.parentPath;\n }\n }\n this.traverse(path);\n },\n });\n\n return found.size === 1 ? [...found][0] : null;\n};\n\n/**\n * Whether the binding pattern `node` introduces a variable named `name`.\n * Recurses through destructuring patterns so all of `const locale`,\n * `const { locale } = …`, `const { locale = fallback } = …`,\n * `const { foo: locale } = …`, `const [locale] = …` and `...locale` are\n * detected — not just a bare identifier.\n */\nconst patternBindsName = (node: any, name: string): boolean => {\n if (!node) return false;\n switch (node.type) {\n case 'Identifier':\n return node.name === name;\n case 'AssignmentPattern':\n // `locale = fallback`\n return patternBindsName(node.left, name);\n case 'RestElement':\n // `...locale`\n return patternBindsName(node.argument, name);\n case 'ArrayPattern':\n return node.elements.some((element: any) =>\n patternBindsName(element, name)\n );\n case 'ObjectPattern':\n return node.properties.some((property: any) =>\n property.type === 'RestElement'\n ? patternBindsName(property.argument, name)\n : // The *value* is the binding target (`{ foo: locale }` binds `locale`).\n patternBindsName(property.value, name)\n );\n default:\n return false;\n }\n};\n\n/**\n * Inserts `const { locale = defaultLocale } = localeRoute.useParams();` once, at\n * the top of the function body. The destructuring form binds only `locale`, so\n * it can never collide with a `params` variable the document already declares.\n * Expression-bodied arrow functions are first converted to a block so the\n * declaration has somewhere to live.\n *\n * No-ops when `locale` is already bound in the function — whether as a simple\n * identifier, through a destructuring pattern (e.g.\n * `const { locale = defaultLocale } = Route.useLoaderData()`), or as a function\n * parameter — so the injected declaration never collides with one the document\n * already provides (which would produce an\n * `Identifier 'locale' has already been declared` parse error).\n *\n * @returns `true` when the declaration was injected, `false` when the document\n * already binds `locale` itself. Callers use this to skip the imports and the\n * route API declaration the injected statement would have needed.\n */\nconst ensureLocaleFromParams = (funcNode: any): boolean => {\n if (funcNode.body?.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const declaredInBody = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some((d: any) => patternBindsName(d.id, 'locale'))\n );\n const declaredInParams = (funcNode.params ?? []).some((param: any) =>\n patternBindsName(param, 'locale')\n );\n if (declaredInBody || declaredInParams) return false;\n\n const statement = parseTsx(\n `const { locale = defaultLocale } = ${LOCALE_ROUTE_API_VARIABLE}.useParams();`\n ).program.body[0];\n funcNode.body.body.unshift(statement);\n return true;\n};\n\n/**\n * Ensures the module-scope `const localeRoute = getRouteApi(\"/<segment>\");`\n * declaration the injected locale statement reads from, inserted right after the\n * import block.\n *\n * Referencing the locale route by id keeps the root document free of an import\n * of `<segment>/route` — importing a child route module from `__root` is\n * discouraged, since the generated route tree already imports the root.\n *\n * No-ops when `localeRoute` is already bound at module scope, reusing that\n * binding rather than redeclaring it (which would be a parse error).\n *\n * @returns `true` when the declaration was inserted, `false` when an existing\n * binding was reused.\n */\nconst ensureLocaleRouteApi = (ast: any, localeSegment: string): boolean => {\n if (isModuleScopeBinding(ast, LOCALE_ROUTE_API_VARIABLE)) return false;\n\n const declaration = parseTsx(\n `const ${LOCALE_ROUTE_API_VARIABLE} = getRouteApi(\"/${localeSegment}\");`\n ).program.body[0];\n ast.program.body.splice(firstInsertIndex(ast), 0, declaration);\n return true;\n};\n\n/**\n * Puts a blank line between the import block and the inserted route API\n * declaration — recast prints a spliced statement flush against the preceding\n * line, which reads as part of the imports.\n */\nconst separateRouteApiDeclaration = (printedCode: string): string =>\n printedCode.replace(\n new RegExp(\n `([^\\\\n])\\\\n(const ${LOCALE_ROUTE_API_VARIABLE} = getRouteApi\\\\()`\n ),\n '$1\\n\\n$2'\n );\n\n/** Sets `lang={locale}` and `dir={getHTMLTextDir(locale)}` on the first `<html>` element. */\nconst setHtmlLangAndDir = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type !== 'JSXIdentifier' || node.name.name !== 'html') {\n this.traverse(path);\n return;\n }\n\n const upsertAttribute = (name: string, value: any): void => {\n const existing = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === name\n ) as any;\n if (existing) {\n existing.value = value;\n } else {\n node.attributes?.push(b.jsxAttribute(b.jsxIdentifier(name), value));\n }\n };\n\n upsertAttribute('lang', b.jsxExpressionContainer(b.identifier('locale')));\n upsertAttribute(\n 'dir',\n b.jsxExpressionContainer(\n b.callExpression(b.identifier('getHTMLTextDir'), [\n b.identifier('locale'),\n ])\n )\n );\n return false;\n },\n });\n};\n\n/**\n * Wraps the `{children}` of a TanStack Start root document with\n * `IntlayerProvider`, deriving the locale from the locale segment route params.\n * Safe and idempotent: bails (returns the original code) when the provider is\n * already present, when no `<html>` document function is found, or when there is\n * no `{children}` placeholder to wrap.\n *\n * @param code Source of the project's `__root` document.\n * @param localeSegment Locale segment directory in use — `{-$locale}` for every\n * routing mode but `prefix-all`, which uses the required `$locale`.\n */\nexport const wrapRootWithProvider = (\n code: string,\n localeSegment: string\n): TransformResult => {\n const ast = parseTsx(code);\n\n if (code.includes('IntlayerProvider')) return { code, status: 'already' };\n\n const funcNode = findHtmlDocumentFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n const template = parseTsx(\n 'const __wrap = <IntlayerProvider locale={locale}>{__child__}</IntlayerProvider>;'\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [path.node];\n path.replace(providerElement);\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n\n if (!wrapped) return { code, status: 'skipped' };\n\n const injectedLocaleDeclaration = ensureLocaleFromParams(funcNode);\n\n ensureNamedImport(ast, 'IntlayerProvider', 'react-intlayer');\n // Only needed by the injected declaration: a document that already derives its\n // own `locale` must not be given unused imports or a stray route API const.\n let insertedRouteApi = false;\n if (injectedLocaleDeclaration) {\n ensureNamedImport(ast, 'getRouteApi', '@tanstack/react-router');\n ensureNamedImport(ast, 'defaultLocale', 'intlayer');\n insertedRouteApi = ensureLocaleRouteApi(ast, localeSegment);\n }\n ensureNamedImport(ast, 'getHTMLTextDir', 'intlayer');\n setHtmlLangAndDir(ast);\n\n const printedCode = recast.print(ast).code;\n\n return {\n code: insertedRouteApi\n ? separateRouteApiDeclaration(printedCode)\n : printedCode,\n status: 'wrapped',\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"transforms.cjs","names":["babelTsParser","isModuleScopeBinding","firstInsertIndex","REQUEST_LOCALE_SERVER_FUNCTION"],"sources":["../../../../../src/init/frameworkSetup/tanstackStart/transforms.ts"],"sourcesContent":["import * as recast from 'recast';\nimport { babelTsParser } from '../../../utils/babelParser';\nimport {\n ensureNamedImport,\n firstInsertIndex,\n isModuleScopeBinding,\n} from '../../utils/astImports';\nimport { REQUEST_LOCALE_SERVER_FUNCTION } from './templates';\n\nconst { builders: b, namedTypes: n } = recast.types;\n\n/** Module-scope identifier bound to the locale route's typed API. */\nconst LOCALE_ROUTE_API_VARIABLE = 'localeRoute';\n\n/** babel-ts parser handles TypeScript *and* JSX. */\nconst parseTsx = (code: string): any =>\n recast.parse(code, { parser: babelTsParser });\n\n/** Result of a source transform. `code` is unchanged for any non-`wrapped` status. */\nexport type TransformResult = {\n code: string;\n status: 'wrapped' | 'already' | 'skipped';\n};\n\n/**\n * Finds the single function that returns the `<html>` document element. Returns\n * `null` when there is no such function, or more than one (ambiguous).\n */\nconst findHtmlDocumentFunction = (ast: any): any => {\n const found = new Set<any>();\n\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type === 'JSXIdentifier' && node.name.name === 'html') {\n // Walk up to the nearest enclosing function node.\n let current = path.parentPath;\n while (current) {\n const value = current.value;\n if (\n value &&\n (n.FunctionDeclaration.check(value) ||\n n.FunctionExpression.check(value) ||\n n.ArrowFunctionExpression.check(value))\n ) {\n found.add(value);\n break;\n }\n current = current.parentPath;\n }\n }\n this.traverse(path);\n },\n });\n\n return found.size === 1 ? [...found][0] : null;\n};\n\n/**\n * Whether the binding pattern `node` introduces a variable named `name`.\n * Recurses through destructuring patterns so all of `const locale`,\n * `const { locale } = …`, `const { locale = fallback } = …`,\n * `const { foo: locale } = …`, `const [locale] = …` and `...locale` are\n * detected — not just a bare identifier.\n */\nconst patternBindsName = (node: any, name: string): boolean => {\n if (!node) return false;\n switch (node.type) {\n case 'Identifier':\n return node.name === name;\n case 'AssignmentPattern':\n // `locale = fallback`\n return patternBindsName(node.left, name);\n case 'RestElement':\n // `...locale`\n return patternBindsName(node.argument, name);\n case 'ArrayPattern':\n return node.elements.some((element: any) =>\n patternBindsName(element, name)\n );\n case 'ObjectPattern':\n return node.properties.some((property: any) =>\n property.type === 'RestElement'\n ? patternBindsName(property.argument, name)\n : // The *value* is the binding target (`{ foo: locale }` binds `locale`).\n patternBindsName(property.value, name)\n );\n default:\n return false;\n }\n};\n\n/**\n * Inserts `const { locale = defaultLocale } = localeRoute.useParams();` once, at\n * the top of the function body. The destructuring form binds only `locale`, so\n * it can never collide with a `params` variable the document already declares.\n * Expression-bodied arrow functions are first converted to a block so the\n * declaration has somewhere to live.\n *\n * No-ops when `locale` is already bound in the function — whether as a simple\n * identifier, through a destructuring pattern (e.g.\n * `const { locale = defaultLocale } = Route.useLoaderData()`), or as a function\n * parameter — so the injected declaration never collides with one the document\n * already provides (which would produce an\n * `Identifier 'locale' has already been declared` parse error).\n *\n * @returns `true` when the declaration was injected, `false` when the document\n * already binds `locale` itself. Callers use this to skip the imports and the\n * route API declaration the injected statement would have needed.\n */\nconst ensureLocaleFromParams = (funcNode: any): boolean => {\n if (funcNode.body?.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n\n const declaredInBody = funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some((d: any) => patternBindsName(d.id, 'locale'))\n );\n const declaredInParams = (funcNode.params ?? []).some((param: any) =>\n patternBindsName(param, 'locale')\n );\n if (declaredInBody || declaredInParams) return false;\n\n const statement = parseTsx(\n `const { locale = defaultLocale } = ${LOCALE_ROUTE_API_VARIABLE}.useParams();`\n ).program.body[0];\n funcNode.body.body.unshift(statement);\n return true;\n};\n\n/**\n * Ensures the module-scope `const localeRoute = getRouteApi(\"/<segment>\");`\n * declaration the injected locale statement reads from, inserted right after the\n * import block.\n *\n * Referencing the locale route by id keeps the root document free of an import\n * of `<segment>/route` — importing a child route module from `__root` is\n * discouraged, since the generated route tree already imports the root.\n *\n * No-ops when `localeRoute` is already bound at module scope, reusing that\n * binding rather than redeclaring it (which would be a parse error).\n *\n * @returns `true` when the declaration was inserted, `false` when an existing\n * binding was reused.\n */\nconst ensureLocaleRouteApi = (ast: any, localeSegment: string): boolean => {\n if (isModuleScopeBinding(ast, LOCALE_ROUTE_API_VARIABLE)) return false;\n\n const declaration = parseTsx(\n `const ${LOCALE_ROUTE_API_VARIABLE} = getRouteApi(\"/${localeSegment}\");`\n ).program.body[0];\n ast.program.body.splice(firstInsertIndex(ast), 0, declaration);\n return true;\n};\n\n/**\n * Puts a blank line between the import block and the inserted route API\n * declaration — recast prints a spliced statement flush against the preceding\n * line, which reads as part of the imports.\n */\nconst separateRouteApiDeclaration = (printedCode: string): string =>\n printedCode.replace(\n new RegExp(\n `([^\\\\n])\\\\n(const ${LOCALE_ROUTE_API_VARIABLE} = getRouteApi\\\\()`\n ),\n '$1\\n\\n$2'\n );\n\n/** Sets `lang={locale}` and `dir={getHTMLTextDir(locale)}` on the first `<html>` element. */\nconst setHtmlLangAndDir = (ast: any): void => {\n recast.visit(ast, {\n visitJSXOpeningElement(path) {\n const node = path.node;\n if (node.name?.type !== 'JSXIdentifier' || node.name.name !== 'html') {\n this.traverse(path);\n return;\n }\n\n const upsertAttribute = (name: string, value: any): void => {\n const existing = node.attributes?.find(\n (attr: any) =>\n attr.type === 'JSXAttribute' && attr.name?.name === name\n ) as any;\n if (existing) {\n existing.value = value;\n } else {\n node.attributes?.push(b.jsxAttribute(b.jsxIdentifier(name), value));\n }\n };\n\n upsertAttribute('lang', b.jsxExpressionContainer(b.identifier('locale')));\n upsertAttribute(\n 'dir',\n b.jsxExpressionContainer(\n b.callExpression(b.identifier('getHTMLTextDir'), [\n b.identifier('locale'),\n ])\n )\n );\n return false;\n },\n });\n};\n\n/**\n * Wraps the first `{children}` expression inside `funcNode` with\n * `<IntlayerProvider locale={locale}>`. Returns whether a wrap happened.\n */\nconst wrapChildrenWithProvider = (funcNode: any): boolean => {\n let wrapped = false;\n recast.visit(funcNode, {\n visitJSXExpressionContainer(path) {\n if (wrapped) return false;\n const expression = path.node.expression;\n if (expression?.type === 'Identifier' && expression.name === 'children') {\n const template = parseTsx(\n 'const __wrap = <IntlayerProvider locale={locale}>{__child__}</IntlayerProvider>;'\n );\n const providerElement = template.program.body[0].declarations[0].init;\n providerElement.children = [path.node];\n path.replace(providerElement);\n wrapped = true;\n return false;\n }\n this.traverse(path);\n },\n });\n return wrapped;\n};\n\n/** Whether `funcNode` already binds `locale` in its body or parameters. */\nconst bindsLocale = (funcNode: any): boolean =>\n (funcNode.body?.type === 'BlockStatement' &&\n funcNode.body.body.some(\n (stmt: any) =>\n stmt.type === 'VariableDeclaration' &&\n stmt.declarations.some((d: any) => patternBindsName(d.id, 'locale'))\n )) ||\n (funcNode.params ?? []).some((param: any) =>\n patternBindsName(param, 'locale')\n );\n\n/**\n * Finds the options object of the root route declaration —\n * `createRootRoute({…})` or `createRootRouteWithContext<…>()({…})`. Returns\n * `null` when absent or not an object literal.\n */\nconst findRootRouteOptions = (ast: any): any => {\n let options: any = null;\n\n recast.visit(ast, {\n visitCallExpression(path) {\n const { callee, arguments: args } = path.node as any;\n const isCreateRootRoute =\n callee.type === 'Identifier' && callee.name === 'createRootRoute';\n const isCreateRootRouteWithContext =\n callee.type === 'CallExpression' &&\n callee.callee?.type === 'Identifier' &&\n callee.callee.name === 'createRootRouteWithContext';\n\n if (\n (isCreateRootRoute || isCreateRootRouteWithContext) &&\n args[0]?.type === 'ObjectExpression'\n ) {\n options = args[0];\n return false;\n }\n this.traverse(path);\n },\n });\n\n return options;\n};\n\n/** Module-scope identifier of the injected request-locale server function. */\nconst REQUEST_LOCALE_FUNCTION_NAME = 'getRequestLocale';\n\n/**\n * Wraps the `{children}` of a TanStack Start root document with\n * `IntlayerProvider` for routing modes without a locale path segment. The\n * locale is resolved per request by a server function exposed through the root\n * `loader`, and read with `Route.useLoaderData()`. Safe and idempotent: bails\n * when the provider is already present, when no `<html>` document or\n * `{children}` is found, or when the root route cannot safely take a loader\n * (no `Route` binding, no options object, or an existing `loader`).\n *\n * @param code Source of the project's `__root` document.\n */\nexport const wrapRootWithRequestLocaleProvider = (\n code: string\n): TransformResult => {\n if (code.includes('IntlayerProvider')) return { code, status: 'already' };\n\n const ast = parseTsx(code);\n\n const funcNode = findHtmlDocumentFunction(ast);\n const rootRouteOptions = findRootRouteOptions(ast);\n const hasLoader = rootRouteOptions?.properties.some(\n (property: any) => (property.key?.name ?? property.key?.value) === 'loader'\n );\n if (\n !funcNode ||\n !rootRouteOptions ||\n hasLoader ||\n !isModuleScopeBinding(ast, 'Route')\n ) {\n return { code, status: 'skipped' };\n }\n\n if (!wrapChildrenWithProvider(funcNode)) return { code, status: 'skipped' };\n\n if (!bindsLocale(funcNode)) {\n if (funcNode.body?.type !== 'BlockStatement') {\n funcNode.body = b.blockStatement([b.returnStatement(funcNode.body)]);\n }\n funcNode.body.body.unshift(\n parseTsx('const locale = Route.useLoaderData();').program.body[0]\n );\n }\n\n rootRouteOptions.properties.unshift(\n b.property(\n 'init',\n b.identifier('loader'),\n b.arrowFunctionExpression(\n [],\n b.callExpression(b.identifier(REQUEST_LOCALE_FUNCTION_NAME), [])\n )\n )\n );\n\n const insertsServerFunction = !isModuleScopeBinding(\n ast,\n REQUEST_LOCALE_FUNCTION_NAME\n );\n if (insertsServerFunction) {\n ast.program.body.splice(\n firstInsertIndex(ast),\n 0,\n parseTsx(REQUEST_LOCALE_SERVER_FUNCTION).program.body[0]\n );\n }\n\n ensureNamedImport(ast, 'IntlayerProvider', 'react-intlayer');\n ensureNamedImport(ast, 'createServerFn', '@tanstack/react-start');\n ensureNamedImport(ast, 'getRequestHeader', '@tanstack/react-start/server');\n ensureNamedImport(ast, 'getCookie', 'intlayer');\n ensureNamedImport(ast, 'getLocale', 'intlayer');\n ensureNamedImport(ast, 'getHTMLTextDir', 'intlayer');\n setHtmlLangAndDir(ast);\n\n const printedCode = recast.print(ast).code;\n\n return {\n // recast prints the spliced declaration flush against the imports.\n code: insertsServerFunction\n ? printedCode.replace(\n new RegExp(`([^\\\\n])\\\\n(const ${REQUEST_LOCALE_FUNCTION_NAME} = )`),\n '$1\\n\\n$2'\n )\n : printedCode,\n status: 'wrapped',\n };\n};\n\n/**\n * Wraps the `{children}` of a TanStack Start root document with\n * `IntlayerProvider`, deriving the locale from the locale segment route params.\n * Safe and idempotent: bails (returns the original code) when the provider is\n * already present, when no `<html>` document function is found, or when there is\n * no `{children}` placeholder to wrap.\n *\n * @param code Source of the project's `__root` document.\n * @param localeSegment Locale segment directory in use — `{-$locale}` for every\n * routing mode but `prefix-all`, which uses the required `$locale`.\n */\nexport const wrapRootWithProvider = (\n code: string,\n localeSegment: string\n): TransformResult => {\n const ast = parseTsx(code);\n\n if (code.includes('IntlayerProvider')) return { code, status: 'already' };\n\n const funcNode = findHtmlDocumentFunction(ast);\n if (!funcNode) return { code, status: 'skipped' };\n\n if (!wrapChildrenWithProvider(funcNode)) return { code, status: 'skipped' };\n\n const injectedLocaleDeclaration = ensureLocaleFromParams(funcNode);\n\n ensureNamedImport(ast, 'IntlayerProvider', 'react-intlayer');\n // Only needed by the injected declaration: a document that already derives its\n // own `locale` must not be given unused imports or a stray route API const.\n let insertedRouteApi = false;\n if (injectedLocaleDeclaration) {\n ensureNamedImport(ast, 'getRouteApi', '@tanstack/react-router');\n ensureNamedImport(ast, 'defaultLocale', 'intlayer');\n insertedRouteApi = ensureLocaleRouteApi(ast, localeSegment);\n }\n ensureNamedImport(ast, 'getHTMLTextDir', 'intlayer');\n setHtmlLangAndDir(ast);\n\n const printedCode = recast.print(ast).code;\n\n return {\n code: insertedRouteApi\n ? separateRouteApiDeclaration(printedCode)\n : printedCode,\n status: 'wrapped',\n };\n};\n"],"mappings":"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"}
@@ -4,146 +4,27 @@ const require_init_utils_configManipulation = require('./utils/configManipulatio
4
4
  const require_init_utils_fileSystem = require('./utils/fileSystem.cjs');
5
5
  const require_init_cms = require('./cms.cjs');
6
6
  const require_initConfig_index = require('../initConfig/index.cjs');
7
+ const require_init_documentationRouter = require('./documentationRouter.cjs');
7
8
  const require_init_frameworkSetup_index = require('./frameworkSetup/index.cjs');
8
9
  const require_init_utils_devScript = require('./utils/devScript.cjs');
9
10
  const require_init_utils_packageManager = require('./utils/packageManager.cjs');
10
11
  const require_init_utils_githubActions = require('./utils/githubActions.cjs');
11
12
  const require_init_utils_jsonParser = require('./utils/jsonParser.cjs');
13
+ const require_init_utils_lintConfig = require('./utils/lintConfig.cjs');
12
14
  const require_init_utils_nextCompilerBabel = require('./utils/nextCompilerBabel.cjs');
13
15
  const require_init_utils_tsConfig = require('./utils/tsConfig.cjs');
16
+ const require_init_utils_urlRoutingFramework = require('./utils/urlRoutingFramework.cjs');
14
17
  const require_init_upgradeIntlayerPackages = require('./upgradeIntlayerPackages.cjs');
15
18
  let node_path = require("node:path");
16
19
  let _intlayer_config_colors = require("@intlayer/config/colors");
17
20
  _intlayer_config_colors = require_runtime.__toESM(_intlayer_config_colors);
18
21
  let _intlayer_config_logger = require("@intlayer/config/logger");
19
22
  let _intlayer_config_node = require("@intlayer/config/node");
23
+ let _intlayer_config_defaultValues = require("@intlayer/config/defaultValues");
20
24
  let _intlayer_config_utils = require("@intlayer/config/utils");
21
25
 
22
26
  //#region src/init/index.ts
23
27
  /**
24
- * Documentation URL Constants
25
- */
26
- const DocumentationRouter = {
27
- NextJS: "https://intlayer.org/doc/environment/nextjs.md",
28
- NextJS_15: "https://intlayer.org/doc/environment/nextjs/15.md",
29
- NextJS_14: "https://intlayer.org/doc/environment/nextjs/14.md",
30
- CRA: "https://intlayer.org/doc/environment/create-react-app.md",
31
- Astro: "https://intlayer.org/doc/environment/astro.md",
32
- ViteAndReact: "https://intlayer.org/doc/environment/vite-and-react.md",
33
- ViteAndReact_ReactRouterV7: "https://intlayer.org/doc/environment/vite-and-react/react-router-v7.md",
34
- ViteAndVue: "https://intlayer.org/doc/environment/vite-and-vue.md",
35
- ViteAndSolid: "https://intlayer.org/doc/environment/vite-and-solid.md",
36
- ViteAndSvelte: "https://intlayer.org/doc/environment/vite-and-svelte.md",
37
- ViteAndPreact: "https://intlayer.org/doc/environment/vite-and-preact.md",
38
- ViteAndLit: "https://intlayer.org/doc/environment/vite-and-lit.md",
39
- ViteAndVanilla: "https://intlayer.org/doc/environment/vite-and-vanilla.md",
40
- Vanilla: "https://intlayer.org/doc/environment/vanilla.md",
41
- TanStackRouter: "https://intlayer.org/doc/environment/tanstack-start.md",
42
- TanStackRouterAndSolid: "https://intlayer.org/doc/environment/tanstack-start/solid.md",
43
- SolidStart: "https://intlayer.org/doc/environment/solid-start.md",
44
- Analog: "https://intlayer.org/doc/environment/analog.md",
45
- Remix: "https://intlayer.org/doc/environment/remix-3.md",
46
- NuxtAndVue: "https://intlayer.org/doc/environment/nuxt-and-vue.md",
47
- Angular: "https://intlayer.org/doc/environment/angular.md",
48
- SvelteKit: "https://intlayer.org/doc/environment/sveltekit.md",
49
- ReactNativeAndExpo: "https://intlayer.org/doc/environment/react-native-and-expo.md",
50
- Lynx: "https://intlayer.org/doc/environment/lynx-and-react.md",
51
- Express: "https://intlayer.org/doc/environment/express.md",
52
- NestJS: "https://intlayer.org/doc/environment/nest.md",
53
- Fastify: "https://intlayer.org/doc/environment/fastify.md",
54
- Hono: "https://intlayer.org/doc/environment/hono.md",
55
- AdonisJS: "https://intlayer.org/doc/environment/adonisjs.md",
56
- Elysia: "https://intlayer.org/doc/environment/elysia.md",
57
- Default: "https://intlayer.org/doc/get-started",
58
- LSP: "https://intlayer.org/doc/lsp.md",
59
- ESLint: "https://intlayer.org/doc/eslint.md",
60
- NextIntl: "https://intlayer.org/blog/intlayer-with-next-intl.md",
61
- ReactI18Next: "https://intlayer.org/blog/intlayer-with-react-i18next.md",
62
- ReactIntl: "https://intlayer.org/blog/intlayer-with-react-intl.md",
63
- NextI18Next: "https://intlayer.org/blog/intlayer-with-next-i18next.md",
64
- VueI18n: "https://intlayer.org/blog/intlayer-with-vue-i18n.md"
65
- };
66
- /**
67
- * The Intlayer lint setup, as `intlayer init` writes it into `.oxlintrc.json`.
68
- *
69
- * Declared locally on purpose: `@intlayer/engine` is installed by every Intlayer
70
- * user, so it must not depend on a lint plugin to write a handful of strings
71
- * into a JSON file. oxlint resolves a plugin's *rules* but not its shipped
72
- * *configs*, so the preset cannot be referenced by name there either.
73
- *
74
- * Mirrors the `recommended` preset of `eslint-plugin-intlayer`; keep in sync
75
- * when a rule is enabled by default there.
76
- */
77
- const LINT_PLUGIN_PACKAGE_NAME = "eslint-plugin-intlayer";
78
- /** Intlayer's generated output — never source, never worth linting. */
79
- const GENERATED_OUTPUT_GLOBS = ["**/.intlayer/**"];
80
- /** Rules of the `recommended` preset, prefixed by the plugin namespace. */
81
- const getRecommendedRules = () => ({
82
- "intlayer/no-raw-text": "warn",
83
- "intlayer/static-dictionary-key": "error",
84
- "intlayer/no-dynamic-field-access": "error"
85
- });
86
- /**
87
- * Helper: Detects the environment and returns the doc URL
88
- */
89
- const getDocumentationUrl = (packageJson) => {
90
- const deps = {
91
- ...packageJson.dependencies,
92
- ...packageJson.devDependencies
93
- };
94
- /**
95
- * Helper to check if a version string matches a specific major version
96
- * Matches: "15", "^15.0.0", "~15.2", "15.0.0-beta"
97
- */
98
- const isVersion = (versionString, major) => {
99
- if (!versionString || typeof versionString !== "string") return false;
100
- return new RegExp(`^[\\^~]?${major}(?:\\.|$)`).test(versionString);
101
- };
102
- if (deps["@lynx-js/react"] || deps["@lynx-js/core"]) return DocumentationRouter.Lynx;
103
- if (deps["react-native"] || deps.expo) return DocumentationRouter.ReactNativeAndExpo;
104
- if (deps.next) {
105
- const version = deps.next;
106
- if (isVersion(version, 14)) return DocumentationRouter.NextJS_14;
107
- if (isVersion(version, 15)) return DocumentationRouter.NextJS_15;
108
- return DocumentationRouter.NextJS;
109
- }
110
- if (deps.nuxt) return DocumentationRouter.NuxtAndVue;
111
- if (deps.astro) return DocumentationRouter.Astro;
112
- if (deps["@sveltejs/kit"]) return DocumentationRouter.SvelteKit;
113
- if (deps["@analogjs/platform"]) return DocumentationRouter.Analog;
114
- if (deps["@solidjs/start"]) return DocumentationRouter.SolidStart;
115
- if (deps.remix || deps["remix-intlayer"]) return DocumentationRouter.Remix;
116
- if (deps["@tanstack/react-router"]) return DocumentationRouter.TanStackRouter;
117
- if (deps["@tanstack/solid-router"]) return DocumentationRouter.TanStackRouterAndSolid;
118
- const reactRouterVersion = deps["react-router"];
119
- if (typeof reactRouterVersion === "string" && (deps["@react-router/fs-routes"] || isVersion(reactRouterVersion, 7))) return DocumentationRouter.ViteAndReact_ReactRouterV7;
120
- if (deps.vite) {
121
- if (deps.vue) return DocumentationRouter.ViteAndVue;
122
- if (deps["solid-js"]) return DocumentationRouter.ViteAndSolid;
123
- if (deps.svelte) return DocumentationRouter.ViteAndSvelte;
124
- if (deps.preact) return DocumentationRouter.ViteAndPreact;
125
- if (deps.lit) return DocumentationRouter.ViteAndLit;
126
- if (deps["vanilla-intlayer"]) return DocumentationRouter.ViteAndVanilla;
127
- return DocumentationRouter.ViteAndReact;
128
- }
129
- if (deps["react-scripts"]) return DocumentationRouter.CRA;
130
- if (deps["@angular/core"]) return DocumentationRouter.Angular;
131
- if (deps.lit) return DocumentationRouter.ViteAndLit;
132
- if (deps["vanilla-intlayer"]) return DocumentationRouter.Vanilla;
133
- if (deps["@nestjs/core"]) return DocumentationRouter.NestJS;
134
- if (deps["@adonisjs/core"]) return DocumentationRouter.AdonisJS;
135
- if (deps.elysia) return DocumentationRouter.Elysia;
136
- if (deps.hono) return DocumentationRouter.Hono;
137
- if (deps.express) return DocumentationRouter.Express;
138
- if (deps.fastify) return DocumentationRouter.Fastify;
139
- if (deps["next-intl"]) return DocumentationRouter.NextIntl;
140
- if (deps["react-i18next"] || deps.i18next) return DocumentationRouter.ReactI18Next;
141
- if (deps["react-intl"]) return DocumentationRouter.ReactIntl;
142
- if (deps["next-i18next"]) return DocumentationRouter.NextI18Next;
143
- if (deps["vue-i18n"]) return DocumentationRouter.VueI18n;
144
- return DocumentationRouter.Default;
145
- };
146
- /**
147
28
  * Resolves the default dev-server URL of the detected framework, used as the
148
29
  * `editor.applicationURL` of the generated configuration file. Frameworks that
149
30
  * embed Vite (Astro, SvelteKit, …) are checked before the bare Vite fallback so
@@ -177,7 +58,7 @@ const initIntlayer = async (rootDir, options) => {
177
58
  (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not parse ${(0, _intlayer_config_logger.colorizePath)("package.json")}.`, { level: "error" });
178
59
  process.exit(1);
179
60
  }
180
- const guideUrl = getDocumentationUrl(packageJson);
61
+ const guideUrl = require_init_documentationRouter.getDocumentationUrl(packageJson);
181
62
  const allDeps = {
182
63
  ...packageJson.dependencies ?? {},
183
64
  ...packageJson.devDependencies ?? {}
@@ -193,11 +74,14 @@ const initIntlayer = async (rootDir, options) => {
193
74
  const linguiPresent = Boolean(allDeps["@lingui/core"] || allDeps["@lingui/react"] || allDeps["@intlayer/lingui"]);
194
75
  const linguiCatalog = linguiPresent ? await require_init_utils_fileSystem.detectLinguiCatalogPattern(rootDir) : null;
195
76
  const linguiCatalogFormat = linguiCatalog?.format ?? (linguiPresent ? "po" : null);
196
- const { packagesToInstall, devPackagesToInstall, compatSyncConfig, compatVitePluginConfig } = require_init_utils_packageManager.detectMissingIntlayerPackages(allDeps, {
77
+ const { packagesToInstall, devPackagesToInstall, compatSyncConfig, compatVitePluginConfig, pendingCompatAdapters } = require_init_utils_packageManager.detectMissingIntlayerPackages(allDeps, {
197
78
  linguiCatalogFormat,
198
79
  dependencies: packageJson.dependencies,
199
80
  devDependencies: packageJson.devDependencies
200
81
  });
82
+ /** Whether the compat adapter for a library is not released yet. */
83
+ const isCompatAdapterPending = (adapterPackage) => pendingCompatAdapters.includes(adapterPackage);
84
+ if (pendingCompatAdapters.length > 0) (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} No released Intlayer adapter yet for ${pendingCompatAdapters.map((adapterPackage) => (0, _intlayer_config_logger.colorize)(adapterPackage, _intlayer_config_colors.MAGENTA)).join(", ")} — keeping your current i18n library and only syncing its catalogs with Intlayer.`, { level: "warn" });
201
85
  const wantsJsonNamespaces = options?.contentStrategy === "json-namespaces" && !compatSyncConfig;
202
86
  if (wantsJsonNamespaces && !allDeps["@intlayer/sync-json-plugin"] && !devPackagesToInstall.includes("@intlayer/sync-json-plugin")) devPackagesToInstall.push("@intlayer/sync-json-plugin");
203
87
  if (!options?.noInstallPackages) {
@@ -223,7 +107,7 @@ const initIntlayer = async (rootDir, options) => {
223
107
  await require_init_upgradeIntlayerPackages.upgradeIntlayerPackages(rootDir);
224
108
  }
225
109
  const gitignorePath = ".gitignore";
226
- if (!options?.noGitignore && await require_init_utils_fileSystem.exists(rootDir, gitignorePath)) {
110
+ if (!options?.noGitignore && !options?.noFrameworkSetup && await require_init_utils_fileSystem.exists(rootDir, gitignorePath)) {
227
111
  const gitignoreContent = await require_init_utils_fileSystem.readFileFromRoot(rootDir, gitignorePath);
228
112
  if (!gitignoreContent.includes("intlayer")) {
229
113
  const newContent = `${gitignoreContent}\n# Intlayer\n.intlayer\n`;
@@ -289,39 +173,25 @@ const initIntlayer = async (rootDir, options) => {
289
173
  } catch {
290
174
  (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not update ${(0, _intlayer_config_logger.colorizePath)(settingsJsonPath)}. You may need to add the LSP settings manually.`, { level: "warn" });
291
175
  }
176
+ if (!options?.noEslint && require_init_utils_packageManager.hasLegacyEslint(allDeps)) (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} ${(0, _intlayer_config_logger.colorize)(require_init_utils_lintConfig.LINT_PLUGIN_PACKAGE_NAME, _intlayer_config_colors.MAGENTA)} needs ESLint ${9}+ (flat config) — skipped the Intlayer lint rules. Upgrade ESLint to enable them: ${(0, _intlayer_config_logger.colorizePath)(require_init_documentationRouter.DocumentationRouter.ESLint)}`, { level: "warn" });
292
177
  if (!options?.noEslint && require_init_utils_packageManager.hasLintTooling(allDeps)) {
293
178
  const oxlintConfigPath = ".oxlintrc.json";
294
- if (await require_init_utils_fileSystem.exists(rootDir, oxlintConfigPath)) try {
295
- const content = await require_init_utils_fileSystem.readFileFromRoot(rootDir, oxlintConfigPath);
296
- const oxlintConfig = require_init_utils_jsonParser.parseJSONWithComments(content);
297
- oxlintConfig.jsPlugins ??= [];
298
- oxlintConfig.rules ??= {};
299
- oxlintConfig.ignorePatterns ??= [];
300
- let oxlintUpdated = false;
301
- for (const glob of GENERATED_OUTPUT_GLOBS) if (!oxlintConfig.ignorePatterns.includes(glob)) {
302
- oxlintConfig.ignorePatterns.push(glob);
303
- oxlintUpdated = true;
304
- }
305
- if (!oxlintConfig.jsPlugins.includes(LINT_PLUGIN_PACKAGE_NAME)) {
306
- oxlintConfig.jsPlugins.push(LINT_PLUGIN_PACKAGE_NAME);
307
- oxlintUpdated = true;
308
- }
309
- for (const [ruleName, severity] of Object.entries(getRecommendedRules())) if (!oxlintConfig.rules[ruleName]) {
310
- oxlintConfig.rules[ruleName] = severity;
311
- oxlintUpdated = true;
312
- }
313
- if (oxlintUpdated) {
179
+ const hasOxlintConfig = await require_init_utils_fileSystem.exists(rootDir, oxlintConfigPath);
180
+ const shouldCreateOxlintConfig = !hasOxlintConfig && Boolean(allDeps.oxlint) && !allDeps.eslint;
181
+ if (hasOxlintConfig || shouldCreateOxlintConfig) try {
182
+ const oxlintConfig = hasOxlintConfig ? require_init_utils_jsonParser.parseJSONWithComments(await require_init_utils_fileSystem.readFileFromRoot(rootDir, oxlintConfigPath)) : {};
183
+ if (require_init_utils_lintConfig.addIntlayerRulesToOxlintConfig(oxlintConfig)) {
314
184
  await require_init_utils_fileSystem.writeFileToRoot(rootDir, oxlintConfigPath, JSON.stringify(oxlintConfig, null, 2));
315
- (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Added the Intlayer lint rules to ${(0, _intlayer_config_logger.colorizePath)(oxlintConfigPath)}`);
185
+ (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} ${hasOxlintConfig ? "Added the Intlayer lint rules to" : "Created"} ${(0, _intlayer_config_logger.colorizePath)(oxlintConfigPath)}`);
316
186
  } else (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} ${(0, _intlayer_config_logger.colorizePath)(oxlintConfigPath)} already includes the Intlayer lint rules`);
317
187
  } catch {
318
- (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not update ${(0, _intlayer_config_logger.colorizePath)(oxlintConfigPath)}. You may need to add ${(0, _intlayer_config_logger.colorize)(LINT_PLUGIN_PACKAGE_NAME, _intlayer_config_colors.MAGENTA)} manually.`, { level: "warn" });
188
+ (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not update ${(0, _intlayer_config_logger.colorizePath)(oxlintConfigPath)}. You may need to add ${(0, _intlayer_config_logger.colorize)(require_init_utils_lintConfig.LINT_PLUGIN_PACKAGE_NAME, _intlayer_config_colors.MAGENTA)} manually.`, { level: "warn" });
319
189
  }
320
190
  else (0, _intlayer_config_logger.logger)([
321
191
  (0, _intlayer_config_logger.colorize)("Intlayer lint rules →", _intlayer_config_colors.MAGENTA),
322
- (0, _intlayer_config_logger.colorize)(`Add ${LINT_PLUGIN_PACKAGE_NAME} to your ESLint flat config to catch hardcoded text and dynamic calls the compiler cannot optimize:`, _intlayer_config_colors.GREY_LIGHT),
323
- (0, _intlayer_config_logger.colorize)(` import intlayer from '${LINT_PLUGIN_PACKAGE_NAME}';\n export default [...intlayer.configs.recommended];`, _intlayer_config_colors.GREY_LIGHT),
324
- (0, _intlayer_config_logger.colorizePath)(DocumentationRouter.ESLint)
192
+ (0, _intlayer_config_logger.colorize)(`Add the ${require_init_utils_lintConfig.LINT_PLUGIN_PACKAGE_NAME} preset to the array your ESLint flat config exports, to catch hardcoded text and dynamic calls the compiler cannot optimize:`, _intlayer_config_colors.GREY_LIGHT),
193
+ (0, _intlayer_config_logger.colorize)(` import intlayer from '${require_init_utils_lintConfig.LINT_PLUGIN_PACKAGE_NAME}';\n\n export default [\n // ...your existing config\n ...intlayer.configs.recommended,\n ];`, _intlayer_config_colors.GREY_LIGHT),
194
+ (0, _intlayer_config_logger.colorizePath)(require_init_documentationRouter.DocumentationRouter.ESLint)
325
195
  ]);
326
196
  }
327
197
  if (!options?.noFrameworkSetup) {
@@ -348,7 +218,7 @@ const initIntlayer = async (rootDir, options) => {
348
218
  }
349
219
  const format = hasTsConfig ? "intlayer.config.ts" : "intlayer.config.mjs";
350
220
  const detectedPattern = await require_init_utils_fileSystem.detectJsonLocalePattern(rootDir);
351
- await require_initConfig_index.initConfig(format, rootDir, {
221
+ const isConfigCreated = await require_initConfig_index.initConfig(format, rootDir, {
352
222
  locales: detectedPattern?.locales,
353
223
  applicationURL: getDefaultApplicationURL(allDeps)
354
224
  });
@@ -383,7 +253,14 @@ const initIntlayer = async (rootDir, options) => {
383
253
  break;
384
254
  }
385
255
  }
386
- if (options?.routingMode) await require_init_cms.setRoutingModeInConfig(rootDir, options.routingMode);
256
+ const hasUrlRouting = require_init_utils_urlRoutingFramework.hasUrlRoutingFramework(allDeps);
257
+ const hasCompatI18nLibrary = require_init_utils_packageManager.detectCompatI18nLibraries(allDeps).length > 0;
258
+ const shouldApplyDefaultRouting = isConfigCreated && options?.routingMode === void 0 && !hasCompatI18nLibrary;
259
+ if (shouldApplyDefaultRouting && !hasUrlRouting) await require_init_cms.setRoutingStorageOnlyInConfig(rootDir);
260
+ const routingMode = options?.routingMode ?? (shouldApplyDefaultRouting && hasUrlRouting ? _intlayer_config_defaultValues.ROUTING_MODE : void 0);
261
+ const enableProxy = options?.enableProxy ?? (shouldApplyDefaultRouting && hasUrlRouting ? true : void 0);
262
+ if (routingMode) await require_init_cms.setRoutingModeInConfig(rootDir, routingMode);
263
+ if (enableProxy !== void 0) await require_init_cms.setEnableProxyInConfig(rootDir, enableProxy);
387
264
  let hasAliasConfiguration = false;
388
265
  for (const file of [
389
266
  "vite.config.ts",
@@ -436,7 +313,8 @@ const initIntlayer = async (rootDir, options) => {
436
313
  await require_init_utils_fileSystem.writeFileToRoot(rootDir, file, updatedContent);
437
314
  (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Updated ${(0, _intlayer_config_logger.colorizePath)(file)} to include Intlayer next-intl compat plugin`);
438
315
  } else (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} ${(0, _intlayer_config_logger.colorizePath)(file)} already includes @intlayer/next-intl/plugin`);
439
- } else if (allDeps["next-translate"] || allDeps["@intlayer/next-translate"]) {
316
+ } else if (isCompatAdapterPending("@intlayer/next-translate")) (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Kept ${(0, _intlayer_config_logger.colorizePath)(file)} untouched (next-translate stays in charge)`);
317
+ else if (allDeps["next-translate"] || allDeps["@intlayer/next-translate"]) {
440
318
  if (!content.includes("@intlayer/next-translate")) {
441
319
  const updatedContent = require_init_utils_configManipulation.updateNextConfigForNextTranslate(content, extension);
442
320
  await require_init_utils_fileSystem.writeFileToRoot(rootDir, file, updatedContent);
@@ -476,7 +354,8 @@ const initIntlayer = async (rootDir, options) => {
476
354
  for (const file of ["nuxt.config.js", "nuxt.config.ts"]) if (await require_init_utils_fileSystem.exists(rootDir, file)) {
477
355
  hasAliasConfiguration = true;
478
356
  const content = await require_init_utils_fileSystem.readFileFromRoot(rootDir, file);
479
- if (allDeps["@nuxtjs/i18n"]) {
357
+ if (isCompatAdapterPending("@intlayer/nuxtjs-i18n")) (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Kept ${(0, _intlayer_config_logger.colorizePath)(file)} untouched (@nuxtjs/i18n stays in charge)`);
358
+ else if (allDeps["@nuxtjs/i18n"]) {
480
359
  if (!content.includes("@intlayer/nuxtjs-i18n")) {
481
360
  const updatedContent = require_init_utils_configManipulation.updateNuxtConfigForNuxtjsI18n(content);
482
361
  await require_init_utils_fileSystem.writeFileToRoot(rootDir, file, updatedContent);
@@ -511,7 +390,7 @@ const initIntlayer = async (rootDir, options) => {
511
390
  if (updatedContent !== content) {
512
391
  await require_init_utils_fileSystem.writeFileToRoot(rootDir, metroConfigFile, updatedContent);
513
392
  (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Updated ${(0, _intlayer_config_logger.colorizePath)(metroConfigFile)} to include the Intlayer Metro plugin`);
514
- } else (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not automatically update ${(0, _intlayer_config_logger.colorizePath)(metroConfigFile)}. Wrap your exported config with ${(0, _intlayer_config_logger.colorize)("configMetroIntlayer", _intlayer_config_colors.MAGENTA)}: ${(0, _intlayer_config_logger.colorizePath)(DocumentationRouter.ReactNativeAndExpo)}`, { level: "warn" });
393
+ } else (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Could not automatically update ${(0, _intlayer_config_logger.colorizePath)(metroConfigFile)}. Wrap your exported config with ${(0, _intlayer_config_logger.colorize)("configMetroIntlayer", _intlayer_config_colors.MAGENTA)}: ${(0, _intlayer_config_logger.colorizePath)(require_init_documentationRouter.DocumentationRouter.ReactNativeAndExpo)}`, { level: "warn" });
515
394
  }
516
395
  } else {
517
396
  const newMetroConfigFile = "metro.config.js";
@@ -610,27 +489,35 @@ const initIntlayer = async (rootDir, options) => {
610
489
  const hasCompatLibrary = Boolean(compatSyncConfig || compatVitePluginConfig);
611
490
  if (hasCompatLibrary) (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} Compat i18n library detected — keeping the app structure untouched (no route restructure, no provider injection)`);
612
491
  if (!hasCompatLibrary) try {
613
- const routingMode = options?.routingMode ?? (0, _intlayer_config_node.getConfiguration)({ baseDir: rootDir }).routing.mode;
492
+ const { routing } = (0, _intlayer_config_node.getConfiguration)({ baseDir: rootDir });
614
493
  await require_init_frameworkSetup_index.setupFramework({
615
494
  rootDir,
616
495
  allDeps,
617
496
  packageManager,
618
497
  useTypeScript: hasTsConfig,
619
- routingMode
498
+ routingMode: routingMode ?? routing.mode,
499
+ enableProxy: enableProxy ?? routing.enableProxy !== false
620
500
  });
621
501
  } catch {
622
502
  (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.x} Framework-specific scaffolding failed. Your existing files were left untouched; follow the documentation to finish the setup.`, { level: "warn" });
623
503
  }
624
504
  }
505
+ if (!options?.skipFinalMessage) logInitSuccessMessage(guideUrl);
506
+ return { guideUrl };
507
+ };
508
+ const logInitSuccessMessage = (guideUrl) => {
625
509
  (0, _intlayer_config_logger.logger)(`${_intlayer_config_logger.v} ${(0, _intlayer_config_logger.colorize)("Intlayer init setup complete.", _intlayer_config_colors.GREEN)}`);
626
510
  (0, _intlayer_config_logger.logger)([
627
511
  (0, _intlayer_config_logger.colorize)("Next →", _intlayer_config_colors.MAGENTA),
628
- (0, _intlayer_config_logger.colorize)(`Follow the instructions in the documentation to complete the setup:`, _intlayer_config_colors.GREY_LIGHT),
512
+ (0, _intlayer_config_logger.colorize)("Follow the instructions in the documentation to complete the setup:", _intlayer_config_colors.GREY_LIGHT),
629
513
  (0, _intlayer_config_logger.colorizePath)(guideUrl)
630
514
  ]);
631
515
  };
632
516
 
633
517
  //#endregion
518
+ exports.DocumentationRouter = require_init_documentationRouter.DocumentationRouter;
634
519
  exports.getDefaultApplicationURL = getDefaultApplicationURL;
520
+ exports.getDocumentationUrl = require_init_documentationRouter.getDocumentationUrl;
635
521
  exports.initIntlayer = initIntlayer;
522
+ exports.logInitSuccessMessage = logInitSuccessMessage;
636
523
  //# sourceMappingURL=index.cjs.map