@inlang/paraglide-js 2.26.0 → 2.28.0

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 (225) hide show
  1. package/README.md +11 -1
  2. package/dist/bundler-plugins/per-locale-build/index.js +14 -7
  3. package/dist/bundler-plugins/per-locale-build/index.js.map +1 -1
  4. package/dist/bundler-plugins/per-locale-build/vite-environments.test.js +237 -4
  5. package/dist/bundler-plugins/per-locale-build/vite-environments.test.js.map +1 -1
  6. package/dist/bundler-plugins/unplugin.d.ts +1 -1
  7. package/dist/bundler-plugins/unplugin.js +79 -10
  8. package/dist/bundler-plugins/unplugin.js.map +1 -1
  9. package/dist/bundler-plugins/unplugin.test.js +334 -1
  10. package/dist/bundler-plugins/unplugin.test.js.map +1 -1
  11. package/dist/bundler-plugins/vite.js +2 -1
  12. package/dist/bundler-plugins/vite.js.map +1 -1
  13. package/dist/bundler-plugins/vite.test.js +1 -1
  14. package/dist/bundler-plugins/vite.test.js.map +1 -1
  15. package/dist/cli/commands/compile/command.js +13 -0
  16. package/dist/cli/commands/compile/command.js.map +1 -1
  17. package/dist/cli/commands/compile/command.test.js +87 -3
  18. package/dist/cli/commands/compile/command.test.js.map +1 -1
  19. package/dist/cli/commands/init/command.d.ts +5 -0
  20. package/dist/cli/commands/init/command.js +216 -44
  21. package/dist/cli/commands/init/command.js.map +1 -1
  22. package/dist/cli/commands/init/command.test.d.ts +1 -0
  23. package/dist/cli/commands/init/command.test.js +123 -0
  24. package/dist/cli/commands/init/command.test.js.map +1 -0
  25. package/dist/cli/defaults.js +2 -2
  26. package/dist/cli/defaults.js.map +1 -1
  27. package/dist/cli/init-options.d.ts +11 -0
  28. package/dist/cli/init-options.js +2 -0
  29. package/dist/cli/init-options.js.map +1 -0
  30. package/dist/cli/steps/add-inlang-check.d.ts +19 -0
  31. package/dist/cli/steps/add-inlang-check.js +60 -0
  32. package/dist/cli/steps/add-inlang-check.js.map +1 -0
  33. package/dist/cli/steps/add-inlang-check.test.d.ts +1 -0
  34. package/dist/cli/steps/add-inlang-check.test.js +88 -0
  35. package/dist/cli/steps/add-inlang-check.test.js.map +1 -0
  36. package/dist/cli/steps/add-message-lint.d.ts +34 -0
  37. package/dist/cli/steps/add-message-lint.js +105 -0
  38. package/dist/cli/steps/add-message-lint.js.map +1 -0
  39. package/dist/cli/steps/add-message-lint.test.d.ts +1 -0
  40. package/dist/cli/steps/add-message-lint.test.js +74 -0
  41. package/dist/cli/steps/add-message-lint.test.js.map +1 -0
  42. package/dist/cli/steps/add-vite-plugin.d.ts +18 -0
  43. package/dist/cli/steps/add-vite-plugin.js +34 -6
  44. package/dist/cli/steps/add-vite-plugin.js.map +1 -1
  45. package/dist/cli/steps/add-vite-plugin.test.js +25 -9
  46. package/dist/cli/steps/add-vite-plugin.test.js.map +1 -1
  47. package/dist/cli/steps/agents-md-suggestion.d.ts +11 -0
  48. package/dist/cli/steps/agents-md-suggestion.js +19 -0
  49. package/dist/cli/steps/agents-md-suggestion.js.map +1 -0
  50. package/dist/cli/steps/agents-md-suggestion.test.d.ts +1 -0
  51. package/dist/cli/steps/agents-md-suggestion.test.js +36 -0
  52. package/dist/cli/steps/agents-md-suggestion.test.js.map +1 -0
  53. package/dist/cli/steps/check-for-uncomitted-changes.d.ts +3 -0
  54. package/dist/cli/steps/check-for-uncomitted-changes.js +15 -3
  55. package/dist/cli/steps/check-for-uncomitted-changes.js.map +1 -1
  56. package/dist/cli/steps/detect-bundler.d.ts +1 -0
  57. package/dist/cli/steps/detect-bundler.js +7 -1
  58. package/dist/cli/steps/detect-bundler.js.map +1 -1
  59. package/dist/cli/steps/initialize-inlang-project.d.ts +4 -3
  60. package/dist/cli/steps/initialize-inlang-project.js +60 -157
  61. package/dist/cli/steps/initialize-inlang-project.js.map +1 -1
  62. package/dist/cli/steps/maybe-add-machine-translation.d.ts +4 -0
  63. package/dist/cli/steps/maybe-add-machine-translation.js +14 -8
  64. package/dist/cli/steps/maybe-add-machine-translation.js.map +1 -1
  65. package/dist/cli/steps/maybe-add-sherlock.d.ts +2 -0
  66. package/dist/cli/steps/maybe-add-sherlock.js +13 -7
  67. package/dist/cli/steps/maybe-add-sherlock.js.map +1 -1
  68. package/dist/cli/steps/maybe-add-sherlock.test.d.ts +1 -0
  69. package/dist/cli/steps/maybe-add-sherlock.test.js +44 -0
  70. package/dist/cli/steps/maybe-add-sherlock.test.js.map +1 -0
  71. package/dist/cli/steps/prompt-for-outdir.d.ts +2 -0
  72. package/dist/cli/steps/prompt-for-outdir.js +4 -0
  73. package/dist/cli/steps/prompt-for-outdir.js.map +1 -1
  74. package/dist/cli/steps/update-package-json.js +8 -13
  75. package/dist/cli/steps/update-package-json.js.map +1 -1
  76. package/dist/cli/steps/update-ts-config.d.ts +6 -0
  77. package/dist/cli/steps/update-ts-config.js +27 -4
  78. package/dist/cli/steps/update-ts-config.js.map +1 -1
  79. package/dist/cli/utils.d.ts +11 -0
  80. package/dist/cli/utils.js +21 -0
  81. package/dist/cli/utils.js.map +1 -1
  82. package/dist/cli/utils.test.d.ts +1 -0
  83. package/dist/cli/utils.test.js +16 -0
  84. package/dist/cli/utils.test.js.map +1 -0
  85. package/dist/compiler/compile-annotation.d.ts +48 -1
  86. package/dist/compiler/compile-annotation.js +243 -10
  87. package/dist/compiler/compile-annotation.js.map +1 -1
  88. package/dist/compiler/compile-bundle.d.ts +7 -2
  89. package/dist/compiler/compile-bundle.js +97 -3
  90. package/dist/compiler/compile-bundle.js.map +1 -1
  91. package/dist/compiler/compile-bundle.test.js +232 -19
  92. package/dist/compiler/compile-bundle.test.js.map +1 -1
  93. package/dist/compiler/compile-lifecycle.test.d.ts +1 -0
  94. package/dist/compiler/compile-lifecycle.test.js +69 -0
  95. package/dist/compiler/compile-lifecycle.test.js.map +1 -0
  96. package/dist/compiler/compile-local-variable.d.ts +3 -0
  97. package/dist/compiler/compile-local-variable.js +5 -2
  98. package/dist/compiler/compile-local-variable.js.map +1 -1
  99. package/dist/compiler/compile-local-variable.test.js +55 -15
  100. package/dist/compiler/compile-local-variable.test.js.map +1 -1
  101. package/dist/compiler/compile-message.d.ts +29 -1
  102. package/dist/compiler/compile-message.exact-number.test.d.ts +1 -0
  103. package/dist/compiler/compile-message.exact-number.test.js +786 -0
  104. package/dist/compiler/compile-message.exact-number.test.js.map +1 -0
  105. package/dist/compiler/compile-message.js +162 -66
  106. package/dist/compiler/compile-message.js.map +1 -1
  107. package/dist/compiler/compile-message.locals.test.d.ts +1 -0
  108. package/dist/compiler/compile-message.locals.test.js +498 -0
  109. package/dist/compiler/compile-message.locals.test.js.map +1 -0
  110. package/dist/compiler/compile-message.test.js +113 -22
  111. package/dist/compiler/compile-message.test.js.map +1 -1
  112. package/dist/compiler/compile-pattern.d.ts +5 -0
  113. package/dist/compiler/compile-pattern.js +6 -18
  114. package/dist/compiler/compile-pattern.js.map +1 -1
  115. package/dist/compiler/compile-pattern.test.js +169 -5
  116. package/dist/compiler/compile-pattern.test.js.map +1 -1
  117. package/dist/compiler/compile-project.js +5 -1
  118. package/dist/compiler/compile-project.js.map +1 -1
  119. package/dist/compiler/compile-project.test.js +1260 -185
  120. package/dist/compiler/compile-project.test.js.map +1 -1
  121. package/dist/compiler/compile.js +36 -17
  122. package/dist/compiler/compile.js.map +1 -1
  123. package/dist/compiler/compile.test.js +71 -1
  124. package/dist/compiler/compile.test.js.map +1 -1
  125. package/dist/compiler/compiler-options.d.ts +41 -0
  126. package/dist/compiler/compiler-options.js.map +1 -1
  127. package/dist/compiler/create-readme.d.ts +4 -1
  128. package/dist/compiler/create-readme.js +33 -125
  129. package/dist/compiler/create-readme.js.map +1 -1
  130. package/dist/compiler/emit-ts-declarations.interop.test.js +2 -2
  131. package/dist/compiler/emit-ts-declarations.interop.test.js.map +1 -1
  132. package/dist/compiler/emit-ts-declarations.test.js +4 -4
  133. package/dist/compiler/emit-ts-declarations.test.js.map +1 -1
  134. package/dist/compiler/index.d.ts +1 -1
  135. package/dist/compiler/index.js +1 -1
  136. package/dist/compiler/index.js.map +1 -1
  137. package/dist/compiler/input-alias.d.ts +21 -0
  138. package/dist/compiler/input-alias.js +42 -0
  139. package/dist/compiler/input-alias.js.map +1 -0
  140. package/dist/compiler/input-alias.test.d.ts +1 -0
  141. package/dist/compiler/input-alias.test.js +58 -0
  142. package/dist/compiler/input-alias.test.js.map +1 -0
  143. package/dist/compiler/message-locals.d.ts +46 -0
  144. package/dist/compiler/message-locals.js +129 -0
  145. package/dist/compiler/message-locals.js.map +1 -0
  146. package/dist/compiler/output-structure/locale-modules.js +7 -1
  147. package/dist/compiler/output-structure/locale-modules.js.map +1 -1
  148. package/dist/compiler/output-structure/locale-modules.test.js +35 -0
  149. package/dist/compiler/output-structure/locale-modules.test.js.map +1 -1
  150. package/dist/compiler/output-structure/message-modules.js +6 -4
  151. package/dist/compiler/output-structure/message-modules.js.map +1 -1
  152. package/dist/compiler/output-structure/message-modules.test.js +35 -0
  153. package/dist/compiler/output-structure/message-modules.test.js.map +1 -1
  154. package/dist/compiler/registry.d.ts +12 -0
  155. package/dist/compiler/registry.js +158 -31
  156. package/dist/compiler/registry.js.map +1 -1
  157. package/dist/compiler/registry.test.d.ts +1 -0
  158. package/dist/compiler/registry.test.js +291 -0
  159. package/dist/compiler/registry.test.js.map +1 -0
  160. package/dist/compiler/runtime/create-runtime.d.ts +2 -0
  161. package/dist/compiler/runtime/create-runtime.js +9 -0
  162. package/dist/compiler/runtime/create-runtime.js.map +1 -1
  163. package/dist/compiler/runtime/extract-locale-from-cookie.js +8 -1
  164. package/dist/compiler/runtime/extract-locale-from-cookie.js.map +1 -1
  165. package/dist/compiler/runtime/extract-locale-from-cookie.test.js +26 -0
  166. package/dist/compiler/runtime/extract-locale-from-cookie.test.js.map +1 -1
  167. package/dist/compiler/runtime/extract-locale-from-header.js +47 -5
  168. package/dist/compiler/runtime/extract-locale-from-header.js.map +1 -1
  169. package/dist/compiler/runtime/extract-locale-from-header.test.js +58 -0
  170. package/dist/compiler/runtime/extract-locale-from-header.test.js.map +1 -1
  171. package/dist/compiler/runtime/get-locale.js +7 -1
  172. package/dist/compiler/runtime/get-locale.js.map +1 -1
  173. package/dist/compiler/runtime/get-locale.test.js +95 -0
  174. package/dist/compiler/runtime/get-locale.test.js.map +1 -1
  175. package/dist/compiler/runtime/localize-href.d.ts +8 -0
  176. package/dist/compiler/runtime/localize-href.js +60 -0
  177. package/dist/compiler/runtime/localize-href.js.map +1 -1
  178. package/dist/compiler/runtime/localize-href.test.js +227 -1
  179. package/dist/compiler/runtime/localize-href.test.js.map +1 -1
  180. package/dist/compiler/runtime/set-locale.js +24 -6
  181. package/dist/compiler/runtime/set-locale.js.map +1 -1
  182. package/dist/compiler/runtime/set-locale.test.js +182 -0
  183. package/dist/compiler/runtime/set-locale.test.js.map +1 -1
  184. package/dist/compiler/runtime/type.d.ts +2 -0
  185. package/dist/compiler/runtime/type.js.map +1 -1
  186. package/dist/compiler/runtime/type.test.js +34 -0
  187. package/dist/compiler/runtime/type.test.js.map +1 -1
  188. package/dist/compiler/runtime/variables.d.ts +2 -0
  189. package/dist/compiler/runtime/variables.js +7 -0
  190. package/dist/compiler/runtime/variables.js.map +1 -1
  191. package/dist/compiler/server/create-server-file.js +24 -0
  192. package/dist/compiler/server/create-server-file.js.map +1 -1
  193. package/dist/compiler/server/create-server-file.test.js +8 -2
  194. package/dist/compiler/server/create-server-file.test.js.map +1 -1
  195. package/dist/compiler/server/middleware.d.ts +8 -2
  196. package/dist/compiler/server/middleware.js +204 -11
  197. package/dist/compiler/server/middleware.js.map +1 -1
  198. package/dist/compiler/server/middleware.test.js +750 -3
  199. package/dist/compiler/server/middleware.test.js.map +1 -1
  200. package/dist/eslint/index.d.ts +4 -0
  201. package/dist/eslint/index.js +8 -0
  202. package/dist/eslint/index.js.map +1 -0
  203. package/dist/eslint/no-dynamic-message-access.d.ts +3 -0
  204. package/dist/eslint/no-dynamic-message-access.js +150 -0
  205. package/dist/eslint/no-dynamic-message-access.js.map +1 -0
  206. package/dist/eslint/no-dynamic-message-access.test.d.ts +1 -0
  207. package/dist/eslint/no-dynamic-message-access.test.js +126 -0
  208. package/dist/eslint/no-dynamic-message-access.test.js.map +1 -0
  209. package/dist/eslint/oxlint.test.d.ts +1 -0
  210. package/dist/eslint/oxlint.test.js +64 -0
  211. package/dist/eslint/oxlint.test.js.map +1 -0
  212. package/dist/services/config/config-schema.d.ts +2 -0
  213. package/dist/services/config/config-schema.js +2 -0
  214. package/dist/services/config/config-schema.js.map +1 -1
  215. package/dist/services/config/load-paraglide-config.test.js +12 -0
  216. package/dist/services/config/load-paraglide-config.test.js.map +1 -1
  217. package/dist/services/env-variables/index.js +1 -1
  218. package/dist/services/env-variables/index.js.map +1 -1
  219. package/dist/services/file-handling/write-output.bench.js +51 -11
  220. package/dist/services/file-handling/write-output.bench.js.map +1 -1
  221. package/dist/services/file-handling/write-output.js +60 -20
  222. package/dist/services/file-handling/write-output.js.map +1 -1
  223. package/dist/services/file-handling/write-output.test.js +175 -0
  224. package/dist/services/file-handling/write-output.test.js.map +1 -1
  225. package/package.json +15 -5
@@ -1 +1 @@
1
- {"version":3,"file":"add-vite-plugin.test.js","sourceRoot":"","sources":["../../../src/cli/steps/add-vite-plugin.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;IAC3C,MAAM,MAAM,GAAG;;;;;;CAMf,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC;QAChB,iBAAiB,EAAE,MAAM;KACzB,CAAC,CAAC,EAAyC,CAAC;IAE7C,MAAM,aAAa,CAAC;QACnB,EAAE,EAAE,EAAE,CAAC,QAAQ;QACf,MAAM,EAAE,iBAAiB;QACzB,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,iBAAiB;KAC7B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,EAAE;QACnE,QAAQ,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;GAS1C,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;IACvF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;CAmBf,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC;QAChB,iBAAiB,EAAE,MAAM;KACzB,CAAC,CAAC,EAAyC,CAAC;IAC7C,MAAM,aAAa,CAAC;QACnB,EAAE,EAAE,EAAE,CAAC,QAAQ;QACf,MAAM,EAAE,iBAAiB;QACzB,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,iBAAiB;KAC7B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,EAAE;QACnE,QAAQ,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"vitest\";\nimport { addVitePlugin } from \"./add-vite-plugin.js\";\nimport { memfs } from \"memfs\";\n\ntest(\"updates a vite.config.ts\", async () => {\n\tconst config = `import { sveltekit } from \"@sveltejs/kit/vite\"\nimport { defineConfig } from \"vite\"\n\nexport default defineConfig({\n\tplugins: [sveltekit()],\n})\n`;\n\n\tconst fs = memfs({\n\t\t\"/vite.config.ts\": config,\n\t}).fs as unknown as typeof import(\"node:fs\");\n\n\tawait addVitePlugin({\n\t\tfs: fs.promises,\n\t\toutdir: \"./src/paraglide\",\n\t\tprojectPath: \"./project.inlang\",\n\t\tconfigPath: \"/vite.config.ts\",\n\t});\n\n\tconst updatedConfig = await fs.promises.readFile(\"/vite.config.ts\", {\n\t\tencoding: \"utf-8\",\n\t});\n\n\texpect(updatedConfig).toMatchInlineSnapshot(`\n\t\t\t\"import { paraglideVitePlugin } from '@inlang/paraglide-js'\n\t\t\timport { sveltekit } from \"@sveltejs/kit/vite\"\n\t\t\timport { defineConfig } from \"vite\"\n\n\t\t\texport default defineConfig({\n\t\t\t\tplugins: [paraglideVitePlugin({ project: './project.inlang', outdir: './src/paraglide' }),sveltekit()],\n\t\t\t})\n\t\t\t\"\n\t\t`);\n});\n\ntest(\"doesn't update configs where the paraglide plugin is already present\", async () => {\n\tconst config = `\n import { sveltekit } from \"@sveltejs/kit/vite\"\n import { paraglideVitePlugin } from \"@inlang/paraglide-js\"\n import { visualizer } from \"rollup-plugin-visualizer\"\n import { defineConfig } from \"vite\"\n \n export default defineConfig({\n plugins: [\n paraglideVitePlugin({\n project: \"./project.inlang\",\n outdir: \"./src/paraglide\",\n }),\n sveltekit(),\n visualizer({\n filename: \"stats.html\",\n emitFile: true,\n }),\n ],\n }) \n`;\n\tconst fs = memfs({\n\t\t\"/vite.config.ts\": config,\n\t}).fs as unknown as typeof import(\"node:fs\");\n\tawait addVitePlugin({\n\t\tfs: fs.promises,\n\t\toutdir: \"./src/paraglide\",\n\t\tprojectPath: \"./project.inlang\",\n\t\tconfigPath: \"/vite.config.ts\",\n\t});\n\n\tconst updatedConfig = await fs.promises.readFile(\"/vite.config.ts\", {\n\t\tencoding: \"utf-8\",\n\t});\n\n\texpect(updatedConfig).toMatch(config);\n});\n"]}
1
+ {"version":3,"file":"add-vite-plugin.test.js","sourceRoot":"","sources":["../../../src/cli/steps/add-vite-plugin.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,IAAI,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE;IAC3C,MAAM,MAAM,GAAG;;;;;;CAMf,CAAC;IAED,MAAM,EAAE,GAAG,KAAK,CAAC;QAChB,iBAAiB,EAAE,MAAM;KACzB,CAAC,CAAC,EAAyC,CAAC;IAE7C,MAAM,aAAa,CAAC;QACnB,EAAE,EAAE,EAAE,CAAC,QAAQ;QACf,MAAM,EAAE,iBAAiB;QACzB,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,iBAAiB;KAC7B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,EAAE;QACnE,QAAQ,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,CAAC,qBAAqB,CAAC;;;;;;;;;EAS3C,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,sEAAsE,EAAE,KAAK,IAAI,EAAE;IACvF,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;CAmBf,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC;QAChB,iBAAiB,EAAE,MAAM;KACzB,CAAC,CAAC,EAAyC,CAAC;IAC7C,MAAM,aAAa,CAAC;QACnB,EAAE,EAAE,EAAE,CAAC,QAAQ;QACf,MAAM,EAAE,iBAAiB;QACzB,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,iBAAiB;KAC7B,CAAC,CAAC;IAEH,MAAM,aAAa,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,EAAE;QACnE,QAAQ,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,MAAM,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;AACvC,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,yEAAyE,EAAE,GAAG,EAAE;IACpF,MAAM,MAAM,GACX,iKAAiK,CAAC;IACnK,MAAM,CACL,gBAAgB,CAAC;QAChB,MAAM;QACN,WAAW,EAAE,kBAAkB;QAC/B,MAAM,EAAE,iBAAiB;KACzB,CAAC,CACF,CAAC,aAAa,CAAC;QACf,EAAE,EAAE,KAAK;QACT,MAAM,EACL,qEAAqE;KACtE,CAAC,CAAC;IACH,MAAM,CACL,gBAAgB,CAAC;QAChB,MAAM,EACL,2EAA2E;QAC5E,WAAW,EAAE,kBAAkB;QAC/B,MAAM,EAAE,iBAAiB;KACzB,CAAC,CACF,CAAC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"vitest\";\nimport { addVitePlugin, updateViteConfig } from \"./add-vite-plugin.js\";\nimport { memfs } from \"memfs\";\n\ntest(\"updates a vite.config.ts\", async () => {\n\tconst config = `import { sveltekit } from \"@sveltejs/kit/vite\"\nimport { defineConfig } from \"vite\"\n\nexport default defineConfig({\n\tplugins: [sveltekit()],\n})\n`;\n\n\tconst fs = memfs({\n\t\t\"/vite.config.ts\": config,\n\t}).fs as unknown as typeof import(\"node:fs\");\n\n\tawait addVitePlugin({\n\t\tfs: fs.promises,\n\t\toutdir: \"./src/paraglide\",\n\t\tprojectPath: \"./project.inlang\",\n\t\tconfigPath: \"/vite.config.ts\",\n\t});\n\n\tconst updatedConfig = await fs.promises.readFile(\"/vite.config.ts\", {\n\t\tencoding: \"utf-8\",\n\t});\n\n\texpect(updatedConfig).toMatchInlineSnapshot(`\n\t\t\"import { paraglideVitePlugin } from '@inlang/paraglide-js'\n\t\timport { sveltekit } from \"@sveltejs/kit/vite\"\n\t\timport { defineConfig } from \"vite\"\n\n\t\texport default defineConfig({\n\t\t\tplugins: [paraglideVitePlugin({ project: \"./project.inlang\", outdir: \"./src/paraglide\" }),sveltekit()],\n\t\t})\n\t\t\"\n\t`);\n});\n\ntest(\"doesn't update configs where the paraglide plugin is already present\", async () => {\n\tconst config = `\n import { sveltekit } from \"@sveltejs/kit/vite\"\n import { paraglideVitePlugin } from \"@inlang/paraglide-js\"\n import { visualizer } from \"rollup-plugin-visualizer\"\n import { defineConfig } from \"vite\"\n \n export default defineConfig({\n plugins: [\n paraglideVitePlugin({\n project: \"./project.inlang\",\n outdir: \"./src/paraglide\",\n }),\n sveltekit(),\n visualizer({\n filename: \"stats.html\",\n emitFile: true,\n }),\n ],\n }) \n`;\n\tconst fs = memfs({\n\t\t\"/vite.config.ts\": config,\n\t}).fs as unknown as typeof import(\"node:fs\");\n\tawait addVitePlugin({\n\t\tfs: fs.promises,\n\t\toutdir: \"./src/paraglide\",\n\t\tprojectPath: \"./project.inlang\",\n\t\tconfigPath: \"/vite.config.ts\",\n\t});\n\n\tconst updatedConfig = await fs.promises.readFile(\"/vite.config.ts\", {\n\t\tencoding: \"utf-8\",\n\t});\n\n\texpect(updatedConfig).toMatch(config);\n});\n\ntest(\"existing integration must match requested paths before unattended reuse\", () => {\n\tconst config =\n\t\t'import {paraglideVitePlugin} from \"@inlang/paraglide-js\"; export default {plugins:[paraglideVitePlugin({project:\"./project.inlang\",outdir:\"./src/paraglide\"})]}';\n\texpect(\n\t\tupdateViteConfig({\n\t\t\tconfig,\n\t\t\tprojectPath: \"./project.inlang\",\n\t\t\toutdir: \"./src/different\",\n\t\t})\n\t).toMatchObject({\n\t\tok: false,\n\t\treason:\n\t\t\t\"Existing Vite plugin paths differ from the requested project/outdir\",\n\t});\n\texpect(\n\t\tupdateViteConfig({\n\t\t\tconfig:\n\t\t\t\t'import {compile} from \"@inlang/paraglide-js\"; export default {plugins:[]}',\n\t\t\tprojectPath: \"./project.inlang\",\n\t\t\toutdir: \"./src/paraglide\",\n\t\t})\n\t).toMatchObject({ ok: false });\n});\n"]}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * The localization section `init` suggests adding to AGENTS.md. `init` only
3
+ * prints it and never writes AGENTS.md.
4
+ */
5
+ export declare function agentsMdSuggestion(args: {
6
+ root: string;
7
+ projectPath: string;
8
+ /** The message files, e.g. `./messages/{locale}.json`. */
9
+ pathPattern: string;
10
+ outdir: string;
11
+ }): string;
@@ -0,0 +1,19 @@
1
+ import { toRelativeDisplayPath } from "../utils.js";
2
+ /**
3
+ * The localization section `init` suggests adding to AGENTS.md. `init` only
4
+ * prints it and never writes AGENTS.md.
5
+ */
6
+ export function agentsMdSuggestion(args) {
7
+ const projectPath = toRelativeDisplayPath(args.root, args.projectPath);
8
+ const pathPattern = toRelativeDisplayPath(args.root, args.pathPattern);
9
+ // an outdir of `./` is the root itself
10
+ const outdir = toRelativeDisplayPath(args.root, args.outdir) || ".";
11
+ return [
12
+ "If you use coding agents, consider adding this to your AGENTS.md:",
13
+ "",
14
+ "## Localization",
15
+ `- Translations are an inlang project. Before localization work, read \`${projectPath}/README.md\`. It covers checks, machine translation and editors. It is git-ignored, so search tools may skip it.`,
16
+ `- Edit messages in \`${pathPattern}\`. Never edit \`${outdir}/\`: Paraglide JS generates it.`,
17
+ ].join("\n");
18
+ }
19
+ //# sourceMappingURL=agents-md-suggestion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-md-suggestion.js","sourceRoot":"","sources":["../../../src/cli/steps/agents-md-suggestion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAMlC;IACA,MAAM,WAAW,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACvE,MAAM,WAAW,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACvE,uCAAuC;IACvC,MAAM,MAAM,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IACpE,OAAO;QACN,mEAAmE;QACnE,EAAE;QACF,iBAAiB;QACjB,0EAA0E,WAAW,kHAAkH;QACvM,wBAAwB,WAAW,oBAAoB,MAAM,iCAAiC;KAC9F,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACd,CAAC","sourcesContent":["import { toRelativeDisplayPath } from \"../utils.js\";\n\n/**\n * The localization section `init` suggests adding to AGENTS.md. `init` only\n * prints it and never writes AGENTS.md.\n */\nexport function agentsMdSuggestion(args: {\n\troot: string;\n\tprojectPath: string;\n\t/** The message files, e.g. `./messages/{locale}.json`. */\n\tpathPattern: string;\n\toutdir: string;\n}): string {\n\tconst projectPath = toRelativeDisplayPath(args.root, args.projectPath);\n\tconst pathPattern = toRelativeDisplayPath(args.root, args.pathPattern);\n\t// an outdir of `./` is the root itself\n\tconst outdir = toRelativeDisplayPath(args.root, args.outdir) || \".\";\n\treturn [\n\t\t\"If you use coding agents, consider adding this to your AGENTS.md:\",\n\t\t\"\",\n\t\t\"## Localization\",\n\t\t`- Translations are an inlang project. Before localization work, read \\`${projectPath}/README.md\\`. It covers checks, machine translation and editors. It is git-ignored, so search tools may skip it.`,\n\t\t`- Edit messages in \\`${pathPattern}\\`. Never edit \\`${outdir}/\\`: Paraglide JS generates it.`,\n\t].join(\"\\n\");\n}\n"]}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ import { expect, test } from "vitest";
2
+ import { agentsMdSuggestion } from "./agents-md-suggestion.js";
3
+ test("the AGENTS.md suggestion names the project, message files and outdir", () => {
4
+ expect(agentsMdSuggestion({
5
+ root: "/app",
6
+ projectPath: "./project.inlang",
7
+ pathPattern: "./messages/{locale}.json",
8
+ outdir: "./src/paraglide",
9
+ })).toBe([
10
+ "If you use coding agents, consider adding this to your AGENTS.md:",
11
+ "",
12
+ "## Localization",
13
+ "- Translations are an inlang project. Before localization work, read `project.inlang/README.md`. It covers checks, machine translation and editors. It is git-ignored, so search tools may skip it.",
14
+ "- Edit messages in `messages/{locale}.json`. Never edit `src/paraglide/`: Paraglide JS generates it.",
15
+ ].join("\n"));
16
+ });
17
+ test("the AGENTS.md suggestion uses custom paths relative to the root", () => {
18
+ const suggestion = agentsMdSuggestion({
19
+ root: "/app",
20
+ projectPath: "/app/i18n/project.inlang",
21
+ pathPattern: "./i18n/{locale}/common.json",
22
+ outdir: "./lib/paraglide/",
23
+ });
24
+ expect(suggestion).toContain("`i18n/project.inlang/README.md`");
25
+ expect(suggestion).toContain("`i18n/{locale}/common.json`");
26
+ expect(suggestion).toContain("Never edit `lib/paraglide/`");
27
+ });
28
+ test("the AGENTS.md suggestion handles an outdir at the root", () => {
29
+ expect(agentsMdSuggestion({
30
+ root: "/app",
31
+ projectPath: "./project.inlang",
32
+ pathPattern: "./messages/{locale}.json",
33
+ outdir: "./",
34
+ })).toContain("Never edit `./`");
35
+ });
36
+ //# sourceMappingURL=agents-md-suggestion.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agents-md-suggestion.test.js","sourceRoot":"","sources":["../../../src/cli/steps/agents-md-suggestion.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,IAAI,CAAC,sEAAsE,EAAE,GAAG,EAAE;IACjF,MAAM,CACL,kBAAkB,CAAC;QAClB,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,0BAA0B;QACvC,MAAM,EAAE,iBAAiB;KACzB,CAAC,CACF,CAAC,IAAI,CACL;QACC,mEAAmE;QACnE,EAAE;QACF,iBAAiB;QACjB,qMAAqM;QACrM,sGAAsG;KACtG,CAAC,IAAI,CAAC,IAAI,CAAC,CACZ,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iEAAiE,EAAE,GAAG,EAAE;IAC5E,MAAM,UAAU,GAAG,kBAAkB,CAAC;QACrC,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,0BAA0B;QACvC,WAAW,EAAE,6BAA6B;QAC1C,MAAM,EAAE,kBAAkB;KAC1B,CAAC,CAAC;IAEH,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAC;IAChE,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;IAC5D,MAAM,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;AAC7D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wDAAwD,EAAE,GAAG,EAAE;IACnE,MAAM,CACL,kBAAkB,CAAC;QAClB,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,kBAAkB;QAC/B,WAAW,EAAE,0BAA0B;QACvC,MAAM,EAAE,IAAI;KACZ,CAAC,CACF,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;AAChC,CAAC,CAAC,CAAC","sourcesContent":["import { expect, test } from \"vitest\";\nimport { agentsMdSuggestion } from \"./agents-md-suggestion.js\";\n\ntest(\"the AGENTS.md suggestion names the project, message files and outdir\", () => {\n\texpect(\n\t\tagentsMdSuggestion({\n\t\t\troot: \"/app\",\n\t\t\tprojectPath: \"./project.inlang\",\n\t\t\tpathPattern: \"./messages/{locale}.json\",\n\t\t\toutdir: \"./src/paraglide\",\n\t\t})\n\t).toBe(\n\t\t[\n\t\t\t\"If you use coding agents, consider adding this to your AGENTS.md:\",\n\t\t\t\"\",\n\t\t\t\"## Localization\",\n\t\t\t\"- Translations are an inlang project. Before localization work, read `project.inlang/README.md`. It covers checks, machine translation and editors. It is git-ignored, so search tools may skip it.\",\n\t\t\t\"- Edit messages in `messages/{locale}.json`. Never edit `src/paraglide/`: Paraglide JS generates it.\",\n\t\t].join(\"\\n\")\n\t);\n});\n\ntest(\"the AGENTS.md suggestion uses custom paths relative to the root\", () => {\n\tconst suggestion = agentsMdSuggestion({\n\t\troot: \"/app\",\n\t\tprojectPath: \"/app/i18n/project.inlang\",\n\t\tpathPattern: \"./i18n/{locale}/common.json\",\n\t\toutdir: \"./lib/paraglide/\",\n\t});\n\n\texpect(suggestion).toContain(\"`i18n/project.inlang/README.md`\");\n\texpect(suggestion).toContain(\"`i18n/{locale}/common.json`\");\n\texpect(suggestion).toContain(\"Never edit `lib/paraglide/`\");\n});\n\ntest(\"the AGENTS.md suggestion handles an outdir at the root\", () => {\n\texpect(\n\t\tagentsMdSuggestion({\n\t\t\troot: \"/app\",\n\t\t\tprojectPath: \"./project.inlang\",\n\t\t\tpathPattern: \"./messages/{locale}.json\",\n\t\t\toutdir: \"./\",\n\t\t})\n\t).toContain(\"Never edit `./`\");\n});\n"]}
@@ -2,4 +2,7 @@ import type { Logger } from "../../services/logger/index.js";
2
2
  import type { CliStep } from "../utils.js";
3
3
  export declare const checkForUncommittedChanges: CliStep<{
4
4
  logger: Logger;
5
+ interactive?: boolean;
6
+ allowDirty?: boolean;
7
+ root?: string;
5
8
  }, unknown>;
@@ -1,8 +1,20 @@
1
1
  import { prompt } from "../utils.js";
2
2
  import childProcess from "node:child_process";
3
3
  export const checkForUncommittedChanges = async (ctx) => {
4
+ if (ctx.allowDirty)
5
+ return ctx;
6
+ let status;
7
+ try {
8
+ status = await execAsync("git status --porcelain", ctx.root);
9
+ }
10
+ catch {
11
+ return ctx;
12
+ }
13
+ if (ctx.interactive === false && status.length > 0) {
14
+ throw new Error("Uncommitted changes found. Commit them or pass --allow-dirty to continue.");
15
+ }
4
16
  try {
5
- if ((await execAsync("git status --porcelain")).toString().length === 0) {
17
+ if (status.length === 0) {
6
18
  return ctx;
7
19
  }
8
20
  ctx.logger.info(`You have uncommitted changes.\n\nCommitting outstanding changes ensures that you don't lose any work, and see the changes the paraglide-js init command introduces.`);
@@ -22,9 +34,9 @@ export const checkForUncommittedChanges = async (ctx) => {
22
34
  return ctx;
23
35
  }
24
36
  };
25
- function execAsync(command) {
37
+ function execAsync(command, cwd) {
26
38
  return new Promise((resolve, reject) => {
27
- childProcess.exec(command, (error, stdout) => {
39
+ childProcess.exec(command, { cwd }, (error, stdout) => {
28
40
  if (error) {
29
41
  reject(error);
30
42
  }
@@ -1 +1 @@
1
- {"version":3,"file":"check-for-uncomitted-changes.js","sourceRoot":"","sources":["../../../src/cli/steps/check-for-uncomitted-changes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,MAAM,0BAA0B,GAGnC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjB,IAAI,CAAC;QACJ,IAAI,CAAC,MAAM,SAAS,CAAC,wBAAwB,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzE,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,IAAI,CACd,qKAAqK,CACrK,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,8BAA8B,EAAE;YAC7D,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;SACd,CAAC,CAAC;QACH,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,GAAG,CAAC;QACZ,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,2BAA2B;QAC3B,OAAO,GAAG,CAAC;IACZ,CAAC;AACF,CAAC,CAAC;AAEF,SAAS,SAAS,CAAC,OAAe;IACjC,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9C,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YAC5C,IAAI,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Logger } from \"../../services/logger/index.js\";\nimport type { CliStep } from \"../utils.js\";\nimport { prompt } from \"../utils.js\";\nimport childProcess from \"node:child_process\";\n\nexport const checkForUncommittedChanges: CliStep<\n\t{ logger: Logger },\n\tunknown\n> = async (ctx) => {\n\ttry {\n\t\tif ((await execAsync(\"git status --porcelain\")).toString().length === 0) {\n\t\t\treturn ctx;\n\t\t}\n\n\t\tctx.logger.info(\n\t\t\t`You have uncommitted changes.\\n\\nCommitting outstanding changes ensures that you don't lose any work, and see the changes the paraglide-js init command introduces.`\n\t\t);\n\t\tconst response = await prompt(\"Continue without committing?\", {\n\t\t\ttype: \"confirm\",\n\t\t\tinitial: false,\n\t\t});\n\t\tif (response === true) {\n\t\t\treturn ctx;\n\t\t} else {\n\t\t\tprocess.exit(0);\n\t\t}\n\t} catch {\n\t\t// git cli is not installed\n\t\treturn ctx;\n\t}\n};\n\nfunction execAsync(command: string) {\n\treturn new Promise<string>((resolve, reject) => {\n\t\tchildProcess.exec(command, (error, stdout) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve(stdout);\n\t\t\t}\n\t\t});\n\t});\n}\n"]}
1
+ {"version":3,"file":"check-for-uncomitted-changes.js","sourceRoot":"","sources":["../../../src/cli/steps/check-for-uncomitted-changes.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,MAAM,0BAA0B,GAQnC,KAAK,EAAE,GAAG,EAAE,EAAE;IACjB,IAAI,GAAG,CAAC,UAAU;QAAE,OAAO,GAAG,CAAC;IAC/B,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACJ,MAAM,GAAG,MAAM,SAAS,CAAC,wBAAwB,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,GAAG,CAAC;IACZ,CAAC;IACD,IAAI,GAAG,CAAC,WAAW,KAAK,KAAK,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACd,2EAA2E,CAC3E,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACJ,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,GAAG,CAAC;QACZ,CAAC;QAED,GAAG,CAAC,MAAM,CAAC,IAAI,CACd,qKAAqK,CACrK,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,8BAA8B,EAAE;YAC7D,IAAI,EAAE,SAAS;YACf,OAAO,EAAE,KAAK;SACd,CAAC,CAAC;QACH,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvB,OAAO,GAAG,CAAC;QACZ,CAAC;aAAM,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACjB,CAAC;IACF,CAAC;IAAC,MAAM,CAAC;QACR,2BAA2B;QAC3B,OAAO,GAAG,CAAC;IACZ,CAAC;AACF,CAAC,CAAC;AAEF,SAAS,SAAS,CAAC,OAAe,EAAE,GAAY;IAC/C,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC9C,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;YACrD,IAAI,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,CAAC;YACf,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Logger } from \"../../services/logger/index.js\";\nimport type { CliStep } from \"../utils.js\";\nimport { prompt } from \"../utils.js\";\nimport childProcess from \"node:child_process\";\n\nexport const checkForUncommittedChanges: CliStep<\n\t{\n\t\tlogger: Logger;\n\t\tinteractive?: boolean;\n\t\tallowDirty?: boolean;\n\t\troot?: string;\n\t},\n\tunknown\n> = async (ctx) => {\n\tif (ctx.allowDirty) return ctx;\n\tlet status: string;\n\ttry {\n\t\tstatus = await execAsync(\"git status --porcelain\", ctx.root);\n\t} catch {\n\t\treturn ctx;\n\t}\n\tif (ctx.interactive === false && status.length > 0) {\n\t\tthrow new Error(\n\t\t\t\"Uncommitted changes found. Commit them or pass --allow-dirty to continue.\"\n\t\t);\n\t}\n\ttry {\n\t\tif (status.length === 0) {\n\t\t\treturn ctx;\n\t\t}\n\n\t\tctx.logger.info(\n\t\t\t`You have uncommitted changes.\\n\\nCommitting outstanding changes ensures that you don't lose any work, and see the changes the paraglide-js init command introduces.`\n\t\t);\n\t\tconst response = await prompt(\"Continue without committing?\", {\n\t\t\ttype: \"confirm\",\n\t\t\tinitial: false,\n\t\t});\n\t\tif (response === true) {\n\t\t\treturn ctx;\n\t\t} else {\n\t\t\tprocess.exit(0);\n\t\t}\n\t} catch {\n\t\t// git cli is not installed\n\t\treturn ctx;\n\t}\n};\n\nfunction execAsync(command: string, cwd?: string) {\n\treturn new Promise<string>((resolve, reject) => {\n\t\tchildProcess.exec(command, { cwd }, (error, stdout) => {\n\t\t\tif (error) {\n\t\t\t\treject(error);\n\t\t\t} else {\n\t\t\t\tresolve(stdout);\n\t\t\t}\n\t\t});\n\t});\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import type { CliStep } from "../utils.js";
2
2
  export declare const detectBundler: CliStep<{
3
3
  fs: typeof import("node:fs/promises");
4
+ root?: string;
4
5
  }, {
5
6
  bundler?: undefined;
6
7
  configPath?: undefined;
@@ -1,5 +1,11 @@
1
+ import path from "node:path";
1
2
  export const detectBundler = async (ctx) => {
2
- const potentialViteConfigPaths = ["./vite.config.js", "./vite.config.ts"];
3
+ const potentialViteConfigPaths = [
4
+ "./vite.config.js",
5
+ "./vite.config.ts",
6
+ "./vite.config.mjs",
7
+ "./vite.config.mts",
8
+ ].map((file) => (ctx.root ? path.resolve(ctx.root, file) : file));
3
9
  const viteConfigPath = await Promise.all(potentialViteConfigPaths.map(async (path) => ({
4
10
  path,
5
11
  exists: await ctx.fs
@@ -1 +1 @@
1
- {"version":3,"file":"detect-bundler.js","sourceRoot":"","sources":["../../../src/cli/steps/detect-bundler.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAUtB,KAAK,EAAE,GAAG,EAAE,EAAE;IACjB,MAAM,wBAAwB,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;IAE1E,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACvC,wBAAwB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI;QACJ,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE;aAClB,MAAM,CAAC,IAAI,CAAC;aACZ,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;aAChB,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;KACpB,CAAC,CAAC,CACH,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAEnE,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO;YACN,GAAG,GAAG;YACN,OAAO,EAAE,SAAS;SAClB,CAAC;IACH,CAAC;IAED,OAAO;QACN,GAAG,GAAG;QACN,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,cAAc;KAC1B,CAAC;AACH,CAAC,CAAC","sourcesContent":["import type { CliStep } from \"../utils.js\";\n\nexport const detectBundler: CliStep<\n\t{ fs: typeof import(\"node:fs/promises\") },\n\t| {\n\t\t\tbundler?: undefined;\n\t\t\tconfigPath?: undefined;\n\t }\n\t| {\n\t\t\tbundler: \"vite\";\n\t\t\tconfigPath: string;\n\t }\n> = async (ctx) => {\n\tconst potentialViteConfigPaths = [\"./vite.config.js\", \"./vite.config.ts\"];\n\n\tconst viteConfigPath = await Promise.all(\n\t\tpotentialViteConfigPaths.map(async (path) => ({\n\t\t\tpath,\n\t\t\texists: await ctx.fs\n\t\t\t\t.access(path)\n\t\t\t\t.then(() => true)\n\t\t\t\t.catch(() => false),\n\t\t}))\n\t).then((results) => results.find((result) => result.exists)?.path);\n\n\tif (!viteConfigPath) {\n\t\treturn {\n\t\t\t...ctx,\n\t\t\tbundler: undefined,\n\t\t};\n\t}\n\n\treturn {\n\t\t...ctx,\n\t\tbundler: \"vite\",\n\t\tconfigPath: viteConfigPath,\n\t};\n};\n"]}
1
+ {"version":3,"file":"detect-bundler.js","sourceRoot":"","sources":["../../../src/cli/steps/detect-bundler.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,CAAC,MAAM,aAAa,GAUtB,KAAK,EAAE,GAAG,EAAE,EAAE;IACjB,MAAM,wBAAwB,GAAG;QAChC,kBAAkB;QAClB,kBAAkB;QAClB,mBAAmB;QACnB,mBAAmB;KACnB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAElE,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACvC,wBAAwB,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7C,IAAI;QACJ,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE;aAClB,MAAM,CAAC,IAAI,CAAC;aACZ,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;aAChB,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;KACpB,CAAC,CAAC,CACH,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC;IAEnE,IAAI,CAAC,cAAc,EAAE,CAAC;QACrB,OAAO;YACN,GAAG,GAAG;YACN,OAAO,EAAE,SAAS;SAClB,CAAC;IACH,CAAC;IAED,OAAO;QACN,GAAG,GAAG;QACN,OAAO,EAAE,MAAM;QACf,UAAU,EAAE,cAAc;KAC1B,CAAC;AACH,CAAC,CAAC","sourcesContent":["import path from \"node:path\";\nimport type { CliStep } from \"../utils.js\";\n\nexport const detectBundler: CliStep<\n\t{ fs: typeof import(\"node:fs/promises\"); root?: string },\n\t| {\n\t\t\tbundler?: undefined;\n\t\t\tconfigPath?: undefined;\n\t }\n\t| {\n\t\t\tbundler: \"vite\";\n\t\t\tconfigPath: string;\n\t }\n> = async (ctx) => {\n\tconst potentialViteConfigPaths = [\n\t\t\"./vite.config.js\",\n\t\t\"./vite.config.ts\",\n\t\t\"./vite.config.mjs\",\n\t\t\"./vite.config.mts\",\n\t].map((file) => (ctx.root ? path.resolve(ctx.root, file) : file));\n\n\tconst viteConfigPath = await Promise.all(\n\t\tpotentialViteConfigPaths.map(async (path) => ({\n\t\t\tpath,\n\t\t\texists: await ctx.fs\n\t\t\t\t.access(path)\n\t\t\t\t.then(() => true)\n\t\t\t\t.catch(() => false),\n\t\t}))\n\t).then((results) => results.find((result) => result.exists)?.path);\n\n\tif (!viteConfigPath) {\n\t\treturn {\n\t\t\t...ctx,\n\t\t\tbundler: undefined,\n\t\t};\n\t}\n\n\treturn {\n\t\t...ctx,\n\t\tbundler: \"vite\",\n\t\tconfigPath: viteConfigPath,\n\t};\n};\n"]}
@@ -1,24 +1,25 @@
1
1
  import { type InlangProject } from "@inlang/sdk";
2
2
  import type { Logger } from "../../services/logger/index.js";
3
3
  import type { CliStep } from "../utils.js";
4
- import fs from "node:fs";
4
+ import type fs from "node:fs";
5
5
  export declare const initializeInlangProject: CliStep<{
6
6
  fs: typeof fs.promises;
7
7
  syncFs: typeof fs;
8
8
  logger: Logger;
9
9
  root: string;
10
+ projectPath?: string;
10
11
  }, {
11
12
  project: InlangProject;
12
- /** Relative path to the project */
13
13
  projectPath: string;
14
14
  }>;
15
15
  export declare const createNewProjectFlow: (ctx: {
16
16
  fs: typeof fs.promises;
17
17
  syncFs: typeof fs;
18
18
  logger: Logger;
19
+ root?: string;
20
+ projectPath?: string;
19
21
  }) => Promise<{
20
22
  project: InlangProject;
21
- /** An absolute path to the created project */
22
23
  projectPath: string;
23
24
  }>;
24
25
  /**
@@ -2,174 +2,77 @@ import { loadProjectFromDirectory, loadProjectInMemory, newProject, saveProjectT
2
2
  import { getNewProjectTemplate } from "../defaults.js";
3
3
  import { DEFAULT_PROJECT_PATH } from "../../services/config/defaults.js";
4
4
  import nodePath from "node:path";
5
- import fs from "node:fs";
6
5
  export const initializeInlangProject = async (ctx) => {
7
- // const existingProjectPaths =
8
- // // checking for undefined if node version is lower than 22
9
- // typeof fs.globSync !== "undefined" ? fs.globSync("*.inlang") : [];
10
- // if (existingProjectPaths.length > 0) {
11
- // const { project, projectPath } = await existingProjectFlow({
12
- // existingProjectPaths,
13
- // fs: ctx.fs,
14
- // syncFs: fs,
15
- // logger: ctx.logger,
16
- // });
17
- // return {
18
- // ...ctx,
19
- // project,
20
- // projectPath,
21
- // };
22
- // } else {
23
- const { project, projectPath } = await createNewProjectFlow(ctx);
24
- return {
25
- ...ctx,
26
- project,
27
- projectPath,
28
- };
29
- // }
6
+ const projectPath = nodePath.resolve(ctx.root, ctx.projectPath ?? DEFAULT_PROJECT_PATH);
7
+ const existing = await ctx.fs
8
+ .access(nodePath.join(projectPath, "settings.json"))
9
+ .then(() => true, () => false);
10
+ if (!existing)
11
+ return { ...ctx, ...(await createNewProjectFlow({ ...ctx, projectPath })) };
12
+ const project = await loadProjectFromDirectory({
13
+ path: projectPath,
14
+ fs: ctx.syncFs,
15
+ });
16
+ const errors = await project.errors.get();
17
+ if (errors.length) {
18
+ await project.close();
19
+ throw new AggregateError(errors, "Existing inlang project has errors.");
20
+ }
21
+ ctx.logger.success("Using the existing inlang project.");
22
+ return { ...ctx, project, projectPath };
30
23
  };
31
- // export const existingProjectFlow = async (ctx: {
32
- // /** An array of absolute paths to existing projects. */
33
- // existingProjectPaths: string[];
34
- // fs: typeof fs.promises;
35
- // syncFs: typeof fs;
36
- // logger: Logger;
37
- // }): Promise<{ project: InlangProject; projectPath: string }> => {
38
- // const NEW_PROJECT_VALUE = "newProject";
39
- // const commonPrefix = getCommonPrefix(ctx.existingProjectPaths);
40
- // const options = ctx.existingProjectPaths.map((path) => {
41
- // return {
42
- // label: path.replace(commonPrefix, ""),
43
- // value: path,
44
- // };
45
- // });
46
- // const selection = (await prompt(
47
- // `Do you want to use an existing Inlang Project or create a new one?`,
48
- // {
49
- // type: "select",
50
- // options: [
51
- // { label: "Create a new project", value: NEW_PROJECT_VALUE },
52
- // ...options,
53
- // ],
54
- // }
55
- // )) as unknown as string; // the prompt type is incorrect
56
- // //if the user wants to create a new project - create one & use it
57
- // if (selection === NEW_PROJECT_VALUE) return createNewProjectFlow(ctx);
58
- // const projectPath = selection;
59
- // const project = await loadProjectFromDirectory({
60
- // path: projectPath,
61
- // fs: ctx.syncFs,
62
- // });
63
- // if ((await project.errors.get()).length > 0) {
64
- // ctx.logger.error(
65
- // "Aborting paragilde initialization. - The selected project has errors. Either fix them, or remove the project and create a new one."
66
- // );
67
- // for (const error of await project.errors.get()) {
68
- // ctx.logger.error(error);
69
- // }
70
- // process.exit(1);
71
- // }
72
- // return { project, projectPath };
73
- // };
74
- // function parseLocaleInput(input: string): {
75
- // validlocales: string[];
76
- // invalidlocales: string[];
77
- // } {
78
- // const locales = input
79
- // .replaceAll(/[,:\s]/g, " ") //replace common separators with spaces
80
- // .split(" ")
81
- // .filter(Boolean) //remove empty segments
82
- // .map((tag) => tag.toLowerCase());
83
- // const validlocales: string[] = [];
84
- // const invalidlocales: string[] = [];
85
- // for (const tag of locales) {
86
- // if (isValidlocale(tag)) {
87
- // validlocales.push(tag);
88
- // } else {
89
- // invalidlocales.push(tag);
90
- // }
91
- // }
92
- // return {
93
- // validlocales,
94
- // invalidlocales,
95
- // };
96
- // }
97
- // async function promptForLocales(
98
- // initialLocales: string[] = []
99
- // ): Promise<string[]> {
100
- // const localesInput =
101
- // (await prompt("Which locales do you want to support?", {
102
- // type: "text",
103
- // placeholder: "en, de-ch, ar",
104
- // initial: initialLocales.length ? initialLocales.join(", ") : undefined,
105
- // })) ?? "";
106
- // const { invalidlocales: invalidLocales, validlocales } =
107
- // parseLocaleInput(localesInput);
108
- // if (validlocales.length === 0) {
109
- // consola.warn("You must specify at least one locale");
110
- // return await promptForLocales();
111
- // }
112
- // if (invalidLocales.length > 0) {
113
- // const message =
114
- // invalidLocales.length === 1
115
- // ? invalidLocales[0] +
116
- // " isn't a valid locale. Please stick to IEEE BCP-47 Language Tags"
117
- // : invalidLocales.map((tag) => `"${tag}"`).join(", ") +
118
- // " aren't valid locales. Please stick to IEEE BCP-47 Language Tags";
119
- // consola.warn(message);
120
- // return await promptForLocales(validlocales);
121
- // }
122
- // return validlocales;
123
- // }
124
24
  export const createNewProjectFlow = async (ctx) => {
25
+ const root = ctx.root ?? process.cwd();
26
+ const projectPath = nodePath.resolve(root, ctx.projectPath ?? DEFAULT_PROJECT_PATH);
125
27
  const settings = getNewProjectTemplate();
126
- const messagePath = settings["plugin.inlang.messageFormat"].pathPattern;
127
- //create the messages dir if it doesn't exist
128
- const messageDir = nodePath.dirname(nodePath.resolve(process.cwd(), messagePath));
129
- await ctx.fs.mkdir(messageDir, { recursive: true });
130
- await Promise.allSettled(settings.locales.map(async (locale) => {
131
- const languageFile = nodePath.resolve(messageDir, locale + ".json");
132
- const exists = await ctx.fs
133
- .access(languageFile)
134
- .then(() => true)
135
- .catch(() => false);
136
- if (exists)
137
- return;
138
- await ctx.fs.writeFile(languageFile, JSON.stringify({
139
- $schema: "https://inlang.com/schema/inlang-message-format",
140
- // add an example message for instant aha moment
141
- example_message: locale === "en"
142
- ? "Hello world {username}"
143
- : "Guten Tag {username}",
144
- }, null, 2));
28
+ // The SDK resolves message paths from the parent of the .inlang directory.
29
+ const relativeMessages = nodePath
30
+ .relative(nodePath.dirname(projectPath), nodePath.join(root, "messages", "{locale}.json"))
31
+ .split(nodePath.sep)
32
+ .join("/");
33
+ settings["plugin.inlang.messageFormat"].pathPattern =
34
+ relativeMessages.startsWith(".")
35
+ ? relativeMessages
36
+ : "./" + relativeMessages;
37
+ await ctx.fs.mkdir(nodePath.join(root, "messages"), { recursive: true });
38
+ await Promise.all(settings.locales.map(async (locale) => {
39
+ const file = nodePath.join(root, "messages", locale + ".json");
40
+ try {
41
+ await ctx.fs.writeFile(file, JSON.stringify({
42
+ $schema: "https://inlang.com/schema/inlang-message-format",
43
+ example_message: locale === "en"
44
+ ? "Hello world {username}"
45
+ : "Guten Tag {username}",
46
+ }, null, 2), { flag: "wx" });
47
+ }
48
+ catch (error) {
49
+ if (error.code !== "EEXIST")
50
+ throw error;
51
+ }
145
52
  }));
146
- const projectPath = DEFAULT_PROJECT_PATH;
147
- //create default project
148
- await ctx.fs.mkdir(projectPath, { recursive: true });
149
- const tempProject = await loadProjectInMemory({
150
- blob: await newProject({
151
- settings,
152
- }),
153
- });
154
- await saveProjectToDirectory({
155
- project: tempProject,
156
- fs: ctx.fs,
157
- path: projectPath,
53
+ const temporary = await loadProjectInMemory({
54
+ blob: await newProject({ settings }),
158
55
  });
56
+ try {
57
+ await saveProjectToDirectory({
58
+ project: temporary,
59
+ fs: ctx.fs,
60
+ path: projectPath,
61
+ });
62
+ }
63
+ finally {
64
+ await temporary.close();
65
+ }
159
66
  const project = await loadProjectFromDirectory({
160
67
  path: projectPath,
161
68
  fs: ctx.syncFs,
162
69
  });
163
- if ((await project.errors.get()).length > 0) {
164
- ctx.logger.error("Failed to create a new inlang project.\n\nThis is likely an internal bug. Please file an issue at https://github.com/opral/inlang-paraglide-js.");
165
- for (const error of await project.errors.get()) {
166
- ctx.logger.error(error);
167
- }
168
- return process.exit(1);
169
- }
170
- else {
171
- ctx.logger.success("Created a new inlang project.");
70
+ const errors = await project.errors.get();
71
+ if (errors.length) {
72
+ await project.close();
73
+ throw new AggregateError(errors, "Failed to create the inlang project.");
172
74
  }
75
+ ctx.logger.success("Created a new inlang project.");
173
76
  return { project, projectPath };
174
77
  };
175
78
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"initialize-inlang-project.js","sourceRoot":"","sources":["../../../src/cli/steps/initialize-inlang-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tloadProjectFromDirectory,\n\tloadProjectInMemory,\n\tnewProject,\n\tsaveProjectToDirectory,\n\ttype InlangProject,\n} from \"@inlang/sdk\";\nimport type { Logger } from \"../../services/logger/index.js\";\nimport type { CliStep } from \"../utils.js\";\nimport { getNewProjectTemplate } from \"../defaults.js\";\nimport { DEFAULT_PROJECT_PATH } from \"../../services/config/defaults.js\";\nimport nodePath from \"node:path\";\nimport fs from \"node:fs\";\n\nexport const initializeInlangProject: CliStep<\n\t{\n\t\tfs: typeof fs.promises;\n\t\tsyncFs: typeof fs;\n\t\tlogger: Logger;\n\t\troot: string;\n\t},\n\t{\n\t\tproject: InlangProject;\n\t\t/** Relative path to the project */\n\t\tprojectPath: string;\n\t}\n> = async (ctx) => {\n\t// const existingProjectPaths =\n\t// \t// checking for undefined if node version is lower than 22\n\t// \ttypeof fs.globSync !== \"undefined\" ? fs.globSync(\"*.inlang\") : [];\n\n\t// if (existingProjectPaths.length > 0) {\n\t// \tconst { project, projectPath } = await existingProjectFlow({\n\t// \t\texistingProjectPaths,\n\t// \t\tfs: ctx.fs,\n\t// \t\tsyncFs: fs,\n\t// \t\tlogger: ctx.logger,\n\t// \t});\n\n\t// \treturn {\n\t// \t\t...ctx,\n\t// \t\tproject,\n\t// \t\tprojectPath,\n\t// \t};\n\t// } else {\n\tconst { project, projectPath } = await createNewProjectFlow(ctx);\n\treturn {\n\t\t...ctx,\n\t\tproject,\n\t\tprojectPath,\n\t};\n\t// }\n};\n\n// export const existingProjectFlow = async (ctx: {\n// \t/** An array of absolute paths to existing projects. */\n// \texistingProjectPaths: string[];\n// \tfs: typeof fs.promises;\n// \tsyncFs: typeof fs;\n// \tlogger: Logger;\n// }): Promise<{ project: InlangProject; projectPath: string }> => {\n// \tconst NEW_PROJECT_VALUE = \"newProject\";\n\n// \tconst commonPrefix = getCommonPrefix(ctx.existingProjectPaths);\n// \tconst options = ctx.existingProjectPaths.map((path) => {\n// \t\treturn {\n// \t\t\tlabel: path.replace(commonPrefix, \"\"),\n// \t\t\tvalue: path,\n// \t\t};\n// \t});\n\n// \tconst selection = (await prompt(\n// \t\t`Do you want to use an existing Inlang Project or create a new one?`,\n// \t\t{\n// \t\t\ttype: \"select\",\n// \t\t\toptions: [\n// \t\t\t\t{ label: \"Create a new project\", value: NEW_PROJECT_VALUE },\n// \t\t\t\t...options,\n// \t\t\t],\n// \t\t}\n// \t)) as unknown as string; // the prompt type is incorrect\n\n// \t//if the user wants to create a new project - create one & use it\n// \tif (selection === NEW_PROJECT_VALUE) return createNewProjectFlow(ctx);\n\n// \tconst projectPath = selection;\n// \tconst project = await loadProjectFromDirectory({\n// \t\tpath: projectPath,\n// \t\tfs: ctx.syncFs,\n// \t});\n\n// \tif ((await project.errors.get()).length > 0) {\n// \t\tctx.logger.error(\n// \t\t\t\"Aborting paragilde initialization. - The selected project has errors. Either fix them, or remove the project and create a new one.\"\n// \t\t);\n// \t\tfor (const error of await project.errors.get()) {\n// \t\t\tctx.logger.error(error);\n// \t\t}\n// \t\tprocess.exit(1);\n// \t}\n\n// \treturn { project, projectPath };\n// };\n\n// function parseLocaleInput(input: string): {\n// \tvalidlocales: string[];\n// \tinvalidlocales: string[];\n// } {\n// \tconst locales = input\n// \t\t.replaceAll(/[,:\\s]/g, \" \") //replace common separators with spaces\n// \t\t.split(\" \")\n// \t\t.filter(Boolean) //remove empty segments\n// \t\t.map((tag) => tag.toLowerCase());\n\n// \tconst validlocales: string[] = [];\n// \tconst invalidlocales: string[] = [];\n\n// \tfor (const tag of locales) {\n// \t\tif (isValidlocale(tag)) {\n// \t\t\tvalidlocales.push(tag);\n// \t\t} else {\n// \t\t\tinvalidlocales.push(tag);\n// \t\t}\n// \t}\n\n// \treturn {\n// \t\tvalidlocales,\n// \t\tinvalidlocales,\n// \t};\n// }\n\n// async function promptForLocales(\n// \tinitialLocales: string[] = []\n// ): Promise<string[]> {\n// \tconst localesInput =\n// \t\t(await prompt(\"Which locales do you want to support?\", {\n// \t\t\ttype: \"text\",\n// \t\t\tplaceholder: \"en, de-ch, ar\",\n// \t\t\tinitial: initialLocales.length ? initialLocales.join(\", \") : undefined,\n// \t\t})) ?? \"\";\n\n// \tconst { invalidlocales: invalidLocales, validlocales } =\n// \t\tparseLocaleInput(localesInput);\n\n// \tif (validlocales.length === 0) {\n// \t\tconsola.warn(\"You must specify at least one locale\");\n// \t\treturn await promptForLocales();\n// \t}\n\n// \tif (invalidLocales.length > 0) {\n// \t\tconst message =\n// \t\t\tinvalidLocales.length === 1\n// \t\t\t\t? invalidLocales[0] +\n// \t\t\t\t\t\" isn't a valid locale. Please stick to IEEE BCP-47 Language Tags\"\n// \t\t\t\t: invalidLocales.map((tag) => `\"${tag}\"`).join(\", \") +\n// \t\t\t\t\t\" aren't valid locales. Please stick to IEEE BCP-47 Language Tags\";\n\n// \t\tconsola.warn(message);\n// \t\treturn await promptForLocales(validlocales);\n// \t}\n\n// \treturn validlocales;\n// }\nexport const createNewProjectFlow = async (ctx: {\n\tfs: typeof fs.promises;\n\tsyncFs: typeof fs;\n\tlogger: Logger;\n}): Promise<{\n\tproject: InlangProject;\n\t/** An absolute path to the created project */\n\tprojectPath: string;\n}> => {\n\tconst settings = getNewProjectTemplate();\n\n\tconst messagePath = settings[\"plugin.inlang.messageFormat\"].pathPattern;\n\n\t//create the messages dir if it doesn't exist\n\tconst messageDir = nodePath.dirname(\n\t\tnodePath.resolve(process.cwd(), messagePath)\n\t);\n\tawait ctx.fs.mkdir(messageDir, { recursive: true });\n\n\tawait Promise.allSettled(\n\t\tsettings.locales.map(async (locale) => {\n\t\t\tconst languageFile = nodePath.resolve(messageDir, locale + \".json\");\n\t\t\tconst exists = await ctx.fs\n\t\t\t\t.access(languageFile)\n\t\t\t\t.then(() => true)\n\t\t\t\t.catch(() => false);\n\t\t\tif (exists) return;\n\t\t\tawait ctx.fs.writeFile(\n\t\t\t\tlanguageFile,\n\t\t\t\tJSON.stringify(\n\t\t\t\t\t{\n\t\t\t\t\t\t$schema: \"https://inlang.com/schema/inlang-message-format\",\n\t\t\t\t\t\t// add an example message for instant aha moment\n\t\t\t\t\t\texample_message:\n\t\t\t\t\t\t\tlocale === \"en\"\n\t\t\t\t\t\t\t\t? \"Hello world {username}\"\n\t\t\t\t\t\t\t\t: \"Guten Tag {username}\",\n\t\t\t\t\t},\n\t\t\t\t\tnull,\n\t\t\t\t\t2\n\t\t\t\t)\n\t\t\t);\n\t\t})\n\t);\n\n\tconst projectPath = DEFAULT_PROJECT_PATH;\n\n\t//create default project\n\tawait ctx.fs.mkdir(projectPath, { recursive: true });\n\n\tconst tempProject = await loadProjectInMemory({\n\t\tblob: await newProject({\n\t\t\tsettings,\n\t\t}),\n\t});\n\n\tawait saveProjectToDirectory({\n\t\tproject: tempProject,\n\t\tfs: ctx.fs,\n\t\tpath: projectPath,\n\t});\n\n\tconst project = await loadProjectFromDirectory({\n\t\tpath: projectPath,\n\t\tfs: ctx.syncFs,\n\t});\n\n\tif ((await project.errors.get()).length > 0) {\n\t\tctx.logger.error(\n\t\t\t\"Failed to create a new inlang project.\\n\\nThis is likely an internal bug. Please file an issue at https://github.com/opral/inlang-paraglide-js.\"\n\t\t);\n\t\tfor (const error of await project.errors.get()) {\n\t\t\tctx.logger.error(error);\n\t\t}\n\t\treturn process.exit(1);\n\t} else {\n\t\tctx.logger.success(\"Created a new inlang project.\");\n\t}\n\treturn { project, projectPath };\n};\n\n/**\n * Get's the common prefix of a set of strings.\n * If only one string is passed the prefix will be the empty string\n *\n * @example\n * ```ts\n * getCommonPrefix([\"foo\", \"foobar\"]) // \"foo\"\n * getCommonPrefix([\"foobar\"]) // \"\"\n * ```\n */\nexport function getCommonPrefix(strings: string[]): string {\n\tconst strs = strings.filter(Boolean);\n\tif (strs.length <= 1) return \"\";\n\n\tconst firstString = strs[0];\n\tif (firstString === undefined) {\n\t\treturn \"\";\n\t}\n\n\treturn strs.reduce(\n\t\t(commonPrefix, str) => longestCommonPrefix(commonPrefix, str),\n\t\tfirstString\n\t);\n}\n\nfunction longestCommonPrefix(strA: string, strB: string): string {\n\tlet commonPrefix = \"\";\n\tfor (let i = 0; i < Math.min(strA.length, strB.length); i++) {\n\t\tif (strA[i] === strB[i]) {\n\t\t\tcommonPrefix += strA[i];\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn commonPrefix;\n}\n\n/**\n * Follows the IETF BCP 47 locale schema with modifications.\n */\nexport const pattern =\n\t\"^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?))(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*))$\";\n\n// const isValidlocale = (locale: string): boolean =>\n// \tRegExp(`${pattern}`).test(locale);\n"]}
1
+ {"version":3,"file":"initialize-inlang-project.js","sourceRoot":"","sources":["../../../src/cli/steps/initialize-inlang-project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tloadProjectFromDirectory,\n\tloadProjectInMemory,\n\tnewProject,\n\tsaveProjectToDirectory,\n\ttype InlangProject,\n} from \"@inlang/sdk\";\nimport type { Logger } from \"../../services/logger/index.js\";\nimport type { CliStep } from \"../utils.js\";\nimport { getNewProjectTemplate } from \"../defaults.js\";\nimport { DEFAULT_PROJECT_PATH } from \"../../services/config/defaults.js\";\nimport nodePath from \"node:path\";\nimport type fs from \"node:fs\";\n\nexport const initializeInlangProject: CliStep<\n\t{\n\t\tfs: typeof fs.promises;\n\t\tsyncFs: typeof fs;\n\t\tlogger: Logger;\n\t\troot: string;\n\t\tprojectPath?: string;\n\t},\n\t{ project: InlangProject; projectPath: string }\n> = async (ctx) => {\n\tconst projectPath = nodePath.resolve(\n\t\tctx.root,\n\t\tctx.projectPath ?? DEFAULT_PROJECT_PATH\n\t);\n\tconst existing = await ctx.fs\n\t\t.access(nodePath.join(projectPath, \"settings.json\"))\n\t\t.then(\n\t\t\t() => true,\n\t\t\t() => false\n\t\t);\n\tif (!existing)\n\t\treturn { ...ctx, ...(await createNewProjectFlow({ ...ctx, projectPath })) };\n\tconst project = await loadProjectFromDirectory({\n\t\tpath: projectPath,\n\t\tfs: ctx.syncFs,\n\t});\n\tconst errors = await project.errors.get();\n\tif (errors.length) {\n\t\tawait project.close();\n\t\tthrow new AggregateError(errors, \"Existing inlang project has errors.\");\n\t}\n\tctx.logger.success(\"Using the existing inlang project.\");\n\treturn { ...ctx, project, projectPath };\n};\n\nexport const createNewProjectFlow = async (ctx: {\n\tfs: typeof fs.promises;\n\tsyncFs: typeof fs;\n\tlogger: Logger;\n\troot?: string;\n\tprojectPath?: string;\n}): Promise<{ project: InlangProject; projectPath: string }> => {\n\tconst root = ctx.root ?? process.cwd();\n\tconst projectPath = nodePath.resolve(\n\t\troot,\n\t\tctx.projectPath ?? DEFAULT_PROJECT_PATH\n\t);\n\tconst settings = getNewProjectTemplate();\n\t// The SDK resolves message paths from the parent of the .inlang directory.\n\tconst relativeMessages = nodePath\n\t\t.relative(\n\t\t\tnodePath.dirname(projectPath),\n\t\t\tnodePath.join(root, \"messages\", \"{locale}.json\")\n\t\t)\n\t\t.split(nodePath.sep)\n\t\t.join(\"/\");\n\tsettings[\"plugin.inlang.messageFormat\"].pathPattern =\n\t\trelativeMessages.startsWith(\".\")\n\t\t\t? relativeMessages\n\t\t\t: \"./\" + relativeMessages;\n\tawait ctx.fs.mkdir(nodePath.join(root, \"messages\"), { recursive: true });\n\tawait Promise.all(\n\t\tsettings.locales.map(async (locale) => {\n\t\t\tconst file = nodePath.join(root, \"messages\", locale + \".json\");\n\t\t\ttry {\n\t\t\t\tawait ctx.fs.writeFile(\n\t\t\t\t\tfile,\n\t\t\t\t\tJSON.stringify(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$schema: \"https://inlang.com/schema/inlang-message-format\",\n\t\t\t\t\t\t\texample_message:\n\t\t\t\t\t\t\t\tlocale === \"en\"\n\t\t\t\t\t\t\t\t\t? \"Hello world {username}\"\n\t\t\t\t\t\t\t\t\t: \"Guten Tag {username}\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\t2\n\t\t\t\t\t),\n\t\t\t\t\t{ flag: \"wx\" }\n\t\t\t\t);\n\t\t\t} catch (error) {\n\t\t\t\tif ((error as NodeJS.ErrnoException).code !== \"EEXIST\") throw error;\n\t\t\t}\n\t\t})\n\t);\n\tconst temporary = await loadProjectInMemory({\n\t\tblob: await newProject({ settings }),\n\t});\n\ttry {\n\t\tawait saveProjectToDirectory({\n\t\t\tproject: temporary,\n\t\t\tfs: ctx.fs,\n\t\t\tpath: projectPath,\n\t\t});\n\t} finally {\n\t\tawait temporary.close();\n\t}\n\tconst project = await loadProjectFromDirectory({\n\t\tpath: projectPath,\n\t\tfs: ctx.syncFs,\n\t});\n\tconst errors = await project.errors.get();\n\tif (errors.length) {\n\t\tawait project.close();\n\t\tthrow new AggregateError(errors, \"Failed to create the inlang project.\");\n\t}\n\tctx.logger.success(\"Created a new inlang project.\");\n\treturn { project, projectPath };\n};\n\n/**\n * Get's the common prefix of a set of strings.\n * If only one string is passed the prefix will be the empty string\n *\n * @example\n * ```ts\n * getCommonPrefix([\"foo\", \"foobar\"]) // \"foo\"\n * getCommonPrefix([\"foobar\"]) // \"\"\n * ```\n */\nexport function getCommonPrefix(strings: string[]): string {\n\tconst strs = strings.filter(Boolean);\n\tif (strs.length <= 1) return \"\";\n\n\tconst firstString = strs[0];\n\tif (firstString === undefined) {\n\t\treturn \"\";\n\t}\n\n\treturn strs.reduce(\n\t\t(commonPrefix, str) => longestCommonPrefix(commonPrefix, str),\n\t\tfirstString\n\t);\n}\n\nfunction longestCommonPrefix(strA: string, strB: string): string {\n\tlet commonPrefix = \"\";\n\tfor (let i = 0; i < Math.min(strA.length, strB.length); i++) {\n\t\tif (strA[i] === strB[i]) {\n\t\t\tcommonPrefix += strA[i];\n\t\t} else {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn commonPrefix;\n}\n\n/**\n * Follows the IETF BCP 47 locale schema with modifications.\n */\nexport const pattern =\n\t\"^((?<grandfathered>(en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang))|((?<language>([A-Za-z]{2,3}(-(?<extlang>[A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?))(-(?<script>[A-Za-z]{4}))?(-(?<region>[A-Za-z]{2}|[0-9]{3}))?(-(?<variant>[A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*))$\";\n\n// const isValidlocale = (locale: string): boolean =>\n// \tRegExp(`${pattern}`).test(locale);\n"]}
@@ -6,10 +6,14 @@ export declare const maybeAddMachineTranslation: CliStep<{
6
6
  projectPath: string;
7
7
  root: string;
8
8
  packageJsonPath: string;
9
+ interactive?: boolean;
10
+ machineTranslation?: boolean;
9
11
  }, {
10
12
  fs: typeof import("node:fs/promises");
11
13
  logger: Logger;
12
14
  projectPath: string;
13
15
  root: string;
14
16
  packageJsonPath: string;
17
+ interactive?: boolean;
18
+ machineTranslation?: boolean;
15
19
  }>;
@@ -1,12 +1,16 @@
1
- import { prompt } from "../utils.js";
1
+ import { prompt, shellArgument } from "../utils.js";
2
2
  import { updatePackageJson } from "./update-package-json.js";
3
3
  import path from "node:path";
4
+ import { INLANG_CLI_VERSION_RANGE } from "./add-inlang-check.js";
4
5
  export const maybeAddMachineTranslation = async (ctx) => {
5
6
  // Prompt for machine translation
6
- const useMachineTranslation = await prompt(`Do you want to set up machine translations?`, {
7
- type: "confirm",
8
- initial: true,
9
- });
7
+ const useMachineTranslation = ctx.machineTranslation ??
8
+ (ctx.interactive === false
9
+ ? false
10
+ : await prompt(`Do you want to set up machine translations?`, {
11
+ type: "confirm",
12
+ initial: true,
13
+ }));
10
14
  if (!useMachineTranslation) {
11
15
  return ctx;
12
16
  }
@@ -21,7 +25,7 @@ export const maybeAddMachineTranslation = async (ctx) => {
21
25
  return devDeps;
22
26
  return {
23
27
  ...devDeps,
24
- "@inlang/cli": "^3.0.0",
28
+ "@inlang/cli": INLANG_CLI_VERSION_RANGE,
25
29
  };
26
30
  },
27
31
  scripts: async (scripts) => {
@@ -30,11 +34,11 @@ export const maybeAddMachineTranslation = async (ctx) => {
30
34
  return scripts;
31
35
  return {
32
36
  ...scripts,
33
- "machine-translate": `inlang machine translate --project ${relativePath}`,
37
+ "machine-translate": `inlang machine translate --project ${shellArgument(relativePath)}`,
34
38
  };
35
39
  },
36
40
  })(ctx);
37
- ctx.logger.success("Added @inlang/cli and machine-translate script to package.json");
41
+ ctx.logger.success("Added a machine-translate script to package.json.");
38
42
  }
39
43
  catch (error) {
40
44
  ctx.logger.error([
@@ -43,6 +47,8 @@ export const maybeAddMachineTranslation = async (ctx) => {
43
47
  "2. Add a machine-translate script to package.json",
44
48
  error,
45
49
  ].join("\n"));
50
+ if (ctx.interactive === false)
51
+ throw error;
46
52
  }
47
53
  return ctx;
48
54
  };