@nutin/cli 1.3.0 → 2.0.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 (284) hide show
  1. package/CHANGELOG.md +122 -8
  2. package/README.md +21 -37
  3. package/bin/add-feature.mjs +9 -0
  4. package/bin/cli.mjs +8 -0
  5. package/bin/create-app.mjs +5 -4
  6. package/bin/update-app.mjs +9 -0
  7. package/lib/index.mjs +81 -30
  8. package/lib/src/add-feature/feature-adder.mjs +83 -0
  9. package/lib/src/add-feature/feature-context-builder.mjs +25 -0
  10. package/lib/src/add-feature/nutin-config-updater.mjs +29 -0
  11. package/lib/src/add-feature/package-json-updater.mjs +49 -0
  12. package/lib/src/common/feature-registry.mjs +11 -0
  13. package/lib/src/common/file-generator.mjs +159 -0
  14. package/lib/src/common/meta-bootstrap-prompt.mjs +33 -0
  15. package/lib/src/common/package-data.mjs +10 -0
  16. package/lib/src/common/package-json-helper.mjs +103 -0
  17. package/lib/src/common/project-meta.mjs +54 -0
  18. package/lib/src/create-app/context-builder.mjs +21 -0
  19. package/lib/src/{git-manager.mjs → create-app/git-manager.mjs} +2 -2
  20. package/lib/src/create-app/json-manager.mjs +73 -0
  21. package/lib/src/create-app/new-app-prompt.mjs +51 -0
  22. package/lib/src/{project-generator.mjs → create-app/project-generator.mjs} +15 -13
  23. package/lib/src/create-app/success-message.mjs +14 -0
  24. package/lib/src/update-app/conflict-report-writer.mjs +31 -0
  25. package/lib/src/update-app/fetch-old-templates.mjs +61 -0
  26. package/lib/src/update-app/project-updater.mjs +136 -0
  27. package/lib/src/update-app/template-differ.mjs +124 -0
  28. package/lib/src/update-app/update-context-builder.mjs +25 -0
  29. package/lib/src/update-app/update-summary-printer.mjs +22 -0
  30. package/lib/src/update-app/version-compare.mjs +12 -0
  31. package/lib/src/utils/print.mjs +36 -0
  32. package/lib/src/utils/promise-exec-alias.mjs +4 -0
  33. package/package.json +17 -12
  34. package/templates/base/.gitignore.hbs +6 -1
  35. package/templates/base/AGENTS.md.hbs +169 -0
  36. package/templates/base/GETTING_STARTED.md.hbs +227 -0
  37. package/templates/base/README.md.hbs +8 -17
  38. package/templates/base/config/languages.json.hbs +6 -0
  39. package/templates/base/config/seo.json.hbs +12 -0
  40. package/templates/base/nutin.config.js.hbs +51 -0
  41. package/templates/base/src/app/components/index.ts.hbs +1 -2
  42. package/templates/base/src/app/globals.d.ts.hbs +3 -15
  43. package/templates/base/src/{libs/guards → app}/guards.ts.hbs +1 -5
  44. package/templates/base/src/app/main.ts.hbs +7 -26
  45. package/templates/base/src/app/services/index.ts.hbs +1 -1
  46. package/templates/base/src/app/views/home/home.view.html.hbs +7 -0
  47. package/templates/base/src/app/views/home/home.view.ts.hbs +1 -56
  48. package/templates/base/src/app/views/index.ts.hbs +1 -0
  49. package/templates/base/src/app/views/not-found/not-found.view.html.hbs +8 -0
  50. package/templates/base/src/app/views/not-found/not-found.view.ts.hbs +4 -37
  51. package/templates/base/src/core/base-classes/base-component/base-component.test.js.hbs +158 -0
  52. package/templates/base/src/core/base-classes/base-component/base-component.ts.hbs +81 -31
  53. package/templates/base/src/core/base-classes/base-component/helpers/catalog.helper.test.js.hbs +124 -0
  54. package/templates/base/src/core/base-classes/base-component/helpers/catalog.helper.ts.hbs +38 -23
  55. package/templates/base/src/core/base-classes/base-component/helpers/children.helper.test.js.hbs +74 -0
  56. package/templates/base/src/core/base-classes/base-component/helpers/children.helper.ts.hbs +1 -1
  57. package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.test.js.hbs +145 -0
  58. package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.ts.hbs +41 -1
  59. package/templates/base/src/core/base-classes/base-component/helpers/event.helper.test.js.hbs +88 -0
  60. package/templates/base/src/core/base-classes/base-component/helpers/event.helper.ts.hbs +13 -14
  61. package/templates/base/src/core/base-classes/base-component/helpers/i18n.helper.test.js.hbs +62 -0
  62. package/templates/base/src/core/base-classes/base-component/helpers/pipe.helper.test.js.hbs +82 -0
  63. package/templates/base/src/core/base-classes/base-component/helpers/security.helper.test.js.hbs +142 -0
  64. package/templates/base/src/core/base-classes/base-component/helpers/security.helper.ts.hbs +67 -22
  65. package/templates/base/src/core/base-classes/base-component/helpers/token.helper.test.js.hbs +183 -0
  66. package/templates/base/src/core/base-classes/component/component.test.js.hbs +85 -0
  67. package/templates/base/src/core/base-classes/component/component.ts.hbs +27 -40
  68. package/templates/base/src/core/base-classes/component/helpers/config.helper.test.js.hbs +58 -0
  69. package/templates/base/src/core/base-classes/component/helpers/config.helper.ts.hbs +17 -0
  70. package/templates/base/src/core/base-classes/component/helpers/data-binding.helper.test.js.hbs +75 -0
  71. package/templates/base/src/core/base-classes/service/service.test.js.hbs +150 -0
  72. package/templates/base/src/core/base-classes/service/service.ts.hbs +26 -20
  73. package/templates/base/src/core/base-classes/view/view.test.js.hbs +74 -0
  74. package/templates/base/src/core/base-classes/view/view.ts.hbs +17 -41
  75. package/templates/base/src/core/config.ts.hbs +7 -0
  76. package/templates/base/src/core/index.ts.hbs +0 -3
  77. package/templates/base/src/core/internals.d.ts.hbs +27 -0
  78. package/templates/base/src/core/nutin-config.d.ts.hbs +4 -0
  79. package/templates/base/src/core/services/event-bus/event-bus.test.js.hbs +67 -3
  80. package/templates/base/src/core/services/event-bus/event-bus.ts.hbs +9 -4
  81. package/templates/base/src/core/services/event-bus/index.ts.hbs +3 -0
  82. package/templates/base/src/core/services/event-bus/lifecycle.facade.test.js.hbs +123 -0
  83. package/templates/base/src/core/services/event-bus/lifecycle.facade.ts.hbs +61 -0
  84. package/templates/base/src/core/services/event-bus/navigation.facade.test.js.hbs +46 -0
  85. package/templates/base/src/core/services/event-bus/navigation.facade.ts.hbs +25 -0
  86. package/templates/base/src/core/services/globals/globals.test.js.hbs +149 -0
  87. package/templates/base/src/core/services/globals/globals.ts.hbs +95 -0
  88. package/templates/base/src/core/services/http-client/helpers/http-builder.helper.test.js.hbs +25 -0
  89. package/templates/base/src/core/services/http-client/helpers/http-manager.helper.test.js.hbs +20 -0
  90. package/templates/base/src/core/services/http-client/http-client.test.js.hbs +43 -0
  91. package/templates/base/src/core/services/i18n/i18n.test.js.hbs +270 -0
  92. package/templates/{features/i18n → base}/src/core/services/i18n/i18n.ts.hbs +60 -9
  93. package/templates/base/src/core/services/index.ts.hbs +5 -6
  94. package/templates/base/src/core/services/pipe-registry/pipe-registry.test.js.hbs +60 -1
  95. package/templates/base/src/core/services/pipe-registry/pipe-registry.ts.hbs +1 -1
  96. package/templates/base/src/core/services/pipe-registry/pipes.test.js.hbs +128 -0
  97. package/templates/base/src/{libs/pipes → core/services/pipe-registry}/pipes.ts.hbs +8 -5
  98. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.test.js.hbs +149 -6
  99. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.ts.hbs +42 -30
  100. package/templates/base/src/core/services/router/helpers/route-guard-manager.helper.test.js.hbs +27 -0
  101. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.test.js.hbs +83 -17
  102. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.ts.hbs +13 -70
  103. package/templates/base/src/core/services/router/router.test.js.hbs +226 -2
  104. package/templates/base/src/core/services/router/router.ts.hbs +40 -9
  105. package/templates/base/src/index.html.hbs +2 -6
  106. package/templates/base/src/styles/_styles.scss.hbs +102 -43
  107. package/templates/base/src/styles/base/_variables.scss.hbs +1 -85
  108. package/templates/base/src/styles/main.scss.hbs +1 -18
  109. package/templates/base/src/styles/tailwind.css.hbs +2 -0
  110. package/templates/base/tools/builder/builder.config.js.hbs +40 -0
  111. package/templates/base/tools/builder/builder.js.hbs +24 -26
  112. package/templates/base/tools/builder/core/app/binary-extensions.test.js.hbs +16 -0
  113. package/templates/base/tools/builder/core/app/compile-ts.js.hbs +16 -0
  114. package/templates/base/tools/builder/core/{copy-static.js.hbs → app/copy-static.js.hbs} +27 -34
  115. package/templates/base/tools/builder/core/app/validate-routes.js.hbs +77 -0
  116. package/templates/base/tools/builder/core/finalize-build.js.hbs +16 -7
  117. package/templates/base/tools/builder/core/{add-tags.js.hbs → html-index/add-tags.js.hbs} +2 -2
  118. package/templates/base/tools/builder/core/html-index/add-tags.test.js.hbs +56 -0
  119. package/templates/base/tools/builder/core/{validate-html.js.hbs → html-index/validate-html.js.hbs} +5 -11
  120. package/templates/base/tools/builder/core/html-templates/merge-templates.js.hbs +152 -0
  121. package/templates/base/tools/builder/core/html-templates/minify-html.js.hbs +15 -0
  122. package/templates/base/tools/builder/core/html-templates/process-html-templates.js.hbs +8 -0
  123. package/templates/{features/i18n/tools/builder/core → base/tools/builder/core/i18n}/build-i18n.js.hbs +6 -17
  124. package/templates/base/tools/builder/core/prod-bundle/compress-files.js.hbs +37 -0
  125. package/templates/base/tools/builder/core/prod-bundle/esbuild.js.hbs +30 -0
  126. package/templates/base/tools/builder/core/{hash-files.js.hbs → prod-bundle/hash-files.js.hbs} +14 -11
  127. package/templates/base/tools/builder/core/seo/generate-robots-txt.js.hbs +51 -0
  128. package/templates/base/tools/builder/core/seo/generate-seo-files.js.hbs +16 -0
  129. package/templates/base/tools/builder/core/seo/generate-seo-html.js.hbs +128 -0
  130. package/templates/base/tools/builder/core/seo/generate-sitemap-xml.js.hbs +43 -0
  131. package/templates/base/tools/builder/core/seo/html-substitutions.js.hbs +99 -0
  132. package/templates/base/tools/builder/core/seo/i18n-resolution.js.hbs +66 -0
  133. package/templates/base/tools/builder/core/seo/route-output.js.hbs +64 -0
  134. package/templates/base/tools/builder/core/seo/ssr/ssr-bundle.js.hbs +54 -0
  135. package/templates/base/tools/builder/core/seo/ssr/ssr-polyfills.js.hbs +132 -0
  136. package/templates/base/tools/builder/core/seo/ssr/ssr-render.js.hbs +95 -0
  137. package/templates/base/tools/builder/core/styles/sass.js.hbs +40 -0
  138. package/templates/base/tools/builder/core/styles/tailwind.js.hbs +84 -0
  139. package/templates/base/tools/dev/dev-serve.js.hbs +26 -18
  140. package/templates/base/tools/dev/serve.js.hbs +11 -1
  141. package/templates/base/tools/dev/watcher.js.hbs +14 -6
  142. package/templates/base/tools/generator/generator.js.hbs +64 -47
  143. package/templates/base/tools/generator/handle-file.js.hbs +17 -44
  144. package/templates/base/tools/generator/handle-file.test.js.hbs +72 -0
  145. package/templates/base/tools/generator/templates/{component.template.js.hbs → component/component.template.js.hbs} +3 -2
  146. package/templates/base/tools/generator/templates/component/component.template.test.js.hbs +23 -0
  147. package/templates/base/tools/generator/templates/html/html.template.js.hbs +2 -0
  148. package/templates/base/tools/generator/templates/html/html.template.test.js.hbs +7 -0
  149. package/templates/base/tools/generator/templates/index.js.hbs +7 -12
  150. package/templates/base/tools/generator/templates/locale/locale.template.js.hbs +4 -0
  151. package/templates/base/tools/generator/templates/locale/locale.template.test.js.hbs +7 -0
  152. package/templates/base/tools/generator/templates/scss/scss.template.js.hbs +1 -0
  153. package/templates/base/tools/generator/templates/scss/scss.template.test.js.hbs +7 -0
  154. package/templates/base/tools/generator/templates/service/service.template.js.hbs +17 -0
  155. package/templates/base/tools/generator/templates/service/service.template.test.js.hbs +22 -0
  156. package/templates/base/tools/generator/templates/test/test.template.js.hbs +10 -0
  157. package/templates/base/tools/generator/templates/test/test.template.test.js.hbs +27 -0
  158. package/templates/base/tools/generator/templates/{view.template.js.hbs → view/view.template.js.hbs} +3 -2
  159. package/templates/base/tools/generator/templates/view/view.template.test.js.hbs +24 -0
  160. package/templates/base/tools/testin-nutin/core/coverage/collect-coverage.js.hbs +39 -0
  161. package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.js.hbs +115 -0
  162. package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.test.js.hbs +74 -0
  163. package/templates/base/tools/testin-nutin/core/coverage/write-summary-report.js.hbs +54 -0
  164. package/templates/base/tools/testin-nutin/core/coverage/write-uncovered-report.js.hbs +44 -0
  165. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/assertion-lib.js.hbs +62 -24
  166. package/templates/base/tools/testin-nutin/core/globals/clock.js.hbs +206 -0
  167. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/jsdom-setup.js.hbs +19 -6
  168. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/register-test-globals.js.hbs +13 -4
  169. package/templates/base/tools/testin-nutin/core/globals/silence-console.js.hbs +23 -0
  170. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/spyon.js.hbs +2 -0
  171. package/templates/base/tools/testin-nutin/core/index.js.hbs +9 -0
  172. package/templates/base/tools/testin-nutin/core/printer.js.hbs +85 -0
  173. package/templates/base/tools/testin-nutin/core/queue/queue.test.js.hbs +46 -0
  174. package/templates/base/tools/testin-nutin/core/queue/test-discovery.test.js.hbs +46 -0
  175. package/templates/base/tools/testin-nutin/core/queue/test-queue.js.hbs +154 -0
  176. package/templates/{features/testinNutin → base/tools}/testin-nutin/core/tests/assertions.test.js.hbs +27 -0
  177. package/templates/base/tools/testin-nutin/core/tests/clock.test.js.hbs +118 -0
  178. package/templates/base/tools/testin-nutin/core/tests/globals-each-all.test.js.hbs +28 -0
  179. package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/create-mock-method.js.hbs +2 -1
  180. package/templates/base/tools/testin-nutin/mocks/create-mock-method.test.js.hbs +64 -0
  181. package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-event-bus.js.hbs +3 -2
  182. package/templates/base/tools/testin-nutin/mocks/mock-event-bus.test.js.hbs +66 -0
  183. package/templates/base/tools/testin-nutin/mocks/mock-http-client.test.js.hbs +26 -0
  184. package/templates/base/tools/testin-nutin/mocks/mock-i18n.test.js.hbs +61 -0
  185. package/templates/base/tools/testin-nutin/mocks/mock-router.test.js.hbs +29 -0
  186. package/templates/base/tools/testin-nutin/runner.js.hbs +100 -0
  187. package/templates/base/tools/testin-nutin/watch-tests.js.hbs +37 -0
  188. package/templates/base/tools/utils/error-exit.js.hbs +8 -0
  189. package/templates/base/tools/utils/format.js.hbs +10 -10
  190. package/templates/base/tools/utils/format.test.js.hbs +45 -0
  191. package/templates/base/tools/utils/get-files-recursive.js.hbs +6 -1
  192. package/templates/base/tools/utils/get-files-recursive.test.js.hbs +49 -0
  193. package/templates/base/tools/utils/get-rel-to-core.test.js.hbs +18 -0
  194. package/templates/base/tools/utils/index.js.hbs +1 -3
  195. package/templates/base/tools/utils/languages.js.hbs +15 -0
  196. package/templates/base/tools/utils/languages.test.js.hbs +16 -0
  197. package/templates/base/tools/utils/print.js.hbs +19 -13
  198. package/templates/base/tools/utils/print.test.js.hbs +60 -0
  199. package/templates/base/tools/utils/prompt-boolean.js.hbs +7 -0
  200. package/templates/base/tools/utils/prompt-boolean.test.js.hbs +54 -0
  201. package/templates/base/tools/utils/run-command.js.hbs +4 -2
  202. package/templates/base/tools/utils/run-command.test.js.hbs +19 -0
  203. package/templates/base/tools/utils/run-script.js.hbs +14 -3
  204. package/templates/base/tools/utils/run-script.test.js.hbs +40 -0
  205. package/templates/features/{deployHelper → docker}/.dockerignore.hbs +4 -4
  206. package/templates/features/docker/tools/docker/Dockerfile.template.hbs +51 -0
  207. package/templates/features/{deployHelper/tools/deployment/nginx.conf.hbs → docker/tools/docker/nginx.conf.template} +4 -2
  208. package/templates/features/docker/tools/docker/scripts/docker-build.js.hbs +20 -0
  209. package/templates/features/docker/tools/docker/scripts/docker-ports.js.hbs +48 -0
  210. package/templates/features/docker/tools/docker/scripts/docker-ports.test.js.hbs +52 -0
  211. package/templates/features/docker/tools/docker/scripts/docker-run.js.hbs +28 -0
  212. package/templates/features/docker/tools/docker/scripts/render-docker-template.js.hbs +23 -0
  213. package/templates/features/docker/tools/docker/scripts/render-docker-template.test.js.hbs +60 -0
  214. package/templates/features/docker/tools/docker/scripts/validate-docker.js.hbs +30 -0
  215. package/lib/src/context-builder.mjs +0 -35
  216. package/lib/src/file-generator.mjs +0 -109
  217. package/lib/src/json-generator.mjs +0 -31
  218. package/lib/src/package-manager.mjs +0 -139
  219. package/lib/src/print.mjs +0 -31
  220. package/lib/src/prompts.mjs +0 -123
  221. package/lib/src/utils.mjs +0 -18
  222. package/lib/src/version.mjs +0 -1
  223. package/templates/base/builder.config.js.hbs +0 -35
  224. package/templates/base/src/app/components/common/anchor/anchor.component.ts.hbs +0 -32
  225. package/templates/base/src/app/components/common/button/button.component.ts.hbs +0 -40
  226. package/templates/base/src/app/dom.test.js.hbs +0 -13
  227. package/templates/base/src/app/services/example/example.service.ts.hbs +0 -18
  228. package/templates/base/src/app/views/home/home.view.test.js.hbs +0 -26
  229. package/templates/base/src/core/services/store/store.test.js.hbs +0 -8
  230. package/templates/base/src/core/services/store/store.ts.hbs +0 -39
  231. package/templates/base/src/core/utils/anchor-manager/anchor-manager.utils.test.js.hbs +0 -0
  232. package/templates/base/src/core/utils/anchor-manager/anchor-manager.utils.ts.hbs +0 -85
  233. package/templates/base/src/core/utils/button-manager/button-manager.utils.test.js.hbs +0 -249
  234. package/templates/base/src/core/utils/button-manager/button-manager.utils.ts.hbs +0 -108
  235. package/templates/base/src/core/utils/helpers/attributes.helper.ts.hbs +0 -50
  236. package/templates/base/src/core/utils/index.ts.hbs +0 -2
  237. package/templates/base/src/libs/index.ts.hbs +0 -4
  238. package/templates/base/src/libs/popover/popover.ts.hbs +0 -145
  239. package/templates/base/src/libs/snackbar/snackbar.ts.hbs +0 -72
  240. package/templates/base/src/styles/base/_functions.scss.hbs +0 -9
  241. package/templates/base/src/styles/core/_libs.scss.hbs +0 -132
  242. package/templates/base/tools/builder/core/esbuild.js.hbs +0 -25
  243. package/templates/base/tools/builder/core/minify-html.js.hbs +0 -60
  244. package/templates/base/tools/builder/core/sass.js.hbs +0 -22
  245. package/templates/base/tools/builder/core/tsc.js.hbs +0 -12
  246. package/templates/base/tools/generator/templates/service.template.js.hbs +0 -17
  247. package/templates/base/tools/utils/export-flags.js.hbs +0 -6
  248. package/templates/features/deployHelper/tools/builder/core/compress-files.js.hbs +0 -56
  249. package/templates/features/deployHelper/tools/deployment/Dockerfile.hbs +0 -30
  250. package/templates/features/i18n/src/app/views/home/locales/en.json.hbs +0 -9
  251. package/templates/features/i18n/src/app/views/not-found/locales/en.json +0 -8
  252. package/templates/features/i18n/src/app/views/not-found/locales/fr.json +0 -8
  253. package/templates/features/i18n/src/core/config.ts.hbs +0 -3
  254. package/templates/features/i18n/src/core/services/i18n/i18n.test.js.hbs +0 -125
  255. package/templates/features/i18n/tools/generator/templates/json.template.js.hbs +0 -8
  256. package/templates/features/i18n/tools/utils/languages.js.hbs +0 -7
  257. package/templates/features/stylinNutin/src/styles/_custom-classes.scss.hbs +0 -9
  258. package/templates/features/stylinNutin/src/styles/base/_mixins.scss.hbs +0 -372
  259. package/templates/features/stylinNutin/src/styles/components/_index.scss.hbs +0 -3
  260. package/templates/features/stylinNutin/src/styles/core/_utilities.scss.hbs +0 -240
  261. package/templates/features/stylinNutin/src/styles/views/_index.scss.hbs +0 -0
  262. package/templates/features/stylinNutin/tools/generator/templates/scss.template.js.hbs +0 -4
  263. package/templates/features/template/src/app/views/home/home.view.html.hbs +0 -56
  264. package/templates/features/template/src/app/views/not-found/not-found.view.html.hbs +0 -19
  265. package/templates/features/template/tools/builder/core/merge-templates.js.hbs +0 -49
  266. package/templates/features/template/tools/generator/templates/html.template.js.hbs +0 -2
  267. package/templates/features/testinNutin/testin-nutin/core/index.js.hbs +0 -5
  268. package/templates/features/testinNutin/testin-nutin/core/src/utils/print.js.hbs +0 -64
  269. package/templates/features/testinNutin/testin-nutin/core/src/utils/test-queue.js.hbs +0 -64
  270. package/templates/features/testinNutin/testin-nutin/core/tests/globals-each-all.test.js.hbs +0 -28
  271. package/templates/features/testinNutin/testin-nutin/mocks/mock-store.js.hbs +0 -38
  272. package/templates/features/testinNutin/testin-nutin/runner.js.hbs +0 -36
  273. package/templates/features/testinNutin/testin-nutin/watch-tests.js.hbs +0 -21
  274. package/templates/features/testinNutin/testin-nutin.config.js.hbs +0 -14
  275. /package/lib/src/{template-compiler.mjs → common/template-compiler.mjs} +0 -0
  276. /package/templates/{features/i18n → base}/src/core/base-classes/base-component/helpers/i18n.helper.ts.hbs +0 -0
  277. /package/templates/{features/i18n → base}/src/core/services/i18n/languages.ts.hbs +0 -0
  278. /package/templates/base/tools/builder/{variables → core/app}/binary-extensions.js.hbs +0 -0
  279. /package/templates/base/tools/builder/core/{paths.js.hbs → app/paths.js.hbs} +0 -0
  280. /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/queue.js.hbs +0 -0
  281. /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/test-discovery.js.hbs +0 -0
  282. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-http-client.js.hbs +0 -0
  283. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-i18n.js.hbs +0 -0
  284. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-router.js.hbs +0 -0
@@ -0,0 +1,227 @@
1
+ # Getting started
2
+
3
+ ## Table of contents
4
+
5
+ - [Project structure](#project-structure)
6
+ - [Running your app](#running-your-app)
7
+ - [Generate components, views and services](#generate-components-views-and-services)
8
+ - [A typical component](#a-typical-component)
9
+ - [Features and configuration](#features-and-configuration)
10
+ - [Styling](#styling)
11
+ - [Global layout components](#global-layout-components)
12
+ - [Testing](#testing)
13
+ - [Useful links](#useful-links)
14
+
15
+ ## Project structure
16
+
17
+ ```
18
+ config/ -- configure i18n and SEO files
19
+
20
+ src/
21
+ app/
22
+ components/
23
+ services/
24
+ views/
25
+ routes.ts
26
+ main.ts
27
+ assets/
28
+ core/ -- Nutin framework source
29
+ styles/
30
+
31
+ tools/ -- build, development, generator and testing
32
+
33
+ nutin.config.js -- features and configuration
34
+ ```
35
+
36
+ ## Running your app
37
+
38
+ ```bash
39
+ # Development
40
+ {{packageManager}} run serve # build and serve
41
+ {{packageManager}} run dev # build and serve with live reload
42
+
43
+ # Build
44
+ {{packageManager}} run build # build the application
45
+ {{packageManager}} run build:prod # build the application for production
46
+ ```
47
+
48
+ ### Imports
49
+
50
+ Imports must use **relative paths** and end with `.js` extension.
51
+
52
+ ```js
53
+ import { Foo } from 'relative/path/to/foo.js';
54
+ ```
55
+
56
+ ## Generate components, views and services
57
+
58
+ Generated elements are automatically exported from the corresponding barrel file:
59
+ `src/app/<components|views|services>/index.ts`.
60
+
61
+
62
+ ```bash
63
+ {{packageManager}} run generate <component|view|service> ELEMENT_NAME
64
+
65
+ # Examples
66
+ {{packageManager}} run generate component my-component # Target dir: src/app/components/my-component/
67
+ {{packageManager}} run generate component path/to/my-component/ # Target dir: src/app/components/path/to/my-component/
68
+ ```
69
+
70
+ ## A typical component
71
+
72
+ ```bash
73
+ components/
74
+ product-card/
75
+ product-card.component.html
76
+ product-card.component.scss
77
+ product-card.component.ts
78
+ ```
79
+
80
+ ```ts
81
+ // The builder injects the component's .html template here.
82
+ const templateFn = (product: Product) => `__TEMPLATE_PLACEHOLDER__`;
83
+
84
+ export class ProductCardComponent extends Component {
85
+ private _product: Product;
86
+
87
+ constructor(mountTarget: HTMLElement, config: Product) {
88
+ super({ templateFn, mountTarget, config });
89
+ this._product = config;
90
+ }
91
+
92
+ // Declares children mounted into the data-component / data-catalog placeholders below.
93
+ public registerChildren(): ComponentConfig[] {
94
+ // Single child, matched to <div data-component="product-details">
95
+ const detailsComponent = {
96
+ selector: `product-details`,
97
+ factory: (el) => new ProductDetailsComponent(
98
+ el,
99
+ { config: this._product.details },
100
+ )
101
+ };
102
+
103
+ // One child per item in _product.tags, matched to <div data-catalog="product-tags">
104
+ const tagsCatalog = this.createCatalogComponents({
105
+ selector: 'product-tags',
106
+ items: this._product.tags,
107
+ component: ProductTagsComponent,
108
+ elementName: 'product-tag'
109
+ });
110
+
111
+ return [
112
+ detailsComponent,
113
+ ...tagsCatalog
114
+ ];
115
+ }
116
+
117
+ // Referenced by the data-event attribute in the template.
118
+ private _goToProductPage(productId: string): void {
119
+ Navigation.navigateTo(`/product/${productId}`);
120
+ }
121
+ }
122
+ ```
123
+
124
+ ```html
125
+ <div
126
+ data-event="click:_goToProductPage:${product.id}"
127
+ class="product-card"
128
+ >
129
+ <h2 class="product-card__name">${product.name}</h2>
130
+ <div data-component="product-details"></div>
131
+ <div data-catalog="product-tags"></div>
132
+ </div>
133
+ ```
134
+
135
+ ```scss
136
+ .product-card {
137
+ // component styles
138
+ }
139
+
140
+ .product-card__name {
141
+ // element styles
142
+ }
143
+ ```
144
+
145
+ A template can also be written directly inline (skip the `.html` file and the placeholder).
146
+
147
+ Defining both an inline template and an external `.html` file, or neither, fails the build.
148
+
149
+ ## Features and configuration
150
+
151
+ Nutin features are enabled in `nutin.config.js`.
152
+
153
+ ### `nutin.config.js`
154
+
155
+ Main Nutin configuration and tool options. See the inline comments for details.
156
+
157
+ - `tailwind`, `i18n`, `generateSEOFiles` — top-level features, `false` by default.
158
+ - `generator.*` — controls what the generator scaffolds.
159
+ - `builder.*` — controls build behavior.
160
+ - `testinNutin.*` — controls TestinNutin.
161
+
162
+ ### `config/seo.json`
163
+
164
+ - Register your routes' description, title and ogImage here.
165
+ - Data is used to generate static `index.html` per route, `robots.txt`, and `sitemap.xml`.
166
+ - Unused if `nutin.config.js -> generateSEOFiles` is disabled.
167
+
168
+ ### `config/languages.json`
169
+
170
+ - Register supported languages for i18n here.
171
+ - Unused if `nutin.config.js -> i18n` is disabled.
172
+
173
+ ## Styling
174
+
175
+ - Nutin uses SASS (`.scss` syntax, compatible with plain CSS) as its default styling solution.
176
+
177
+ - Tailwind CSS v4 is also supported as an optional utility-first CSS layer.
178
+
179
+ **Note:** Installing Tailwind CSS dependencies may print `npm warn install-scripts`. This is expected with npm 12's default install-script allowlisting and is safe to ignore.
180
+
181
+ ## Global layout components
182
+
183
+ If you need components to render outside `<main>` (such as a header or footer), register them with `registerGlobals()` in `main.ts` constructor.
184
+
185
+ Global components are mounted directly in `<body>` and remain present across route changes. Use `before` for components that should appear before `<main>` and `after` for components that should appear after it.
186
+
187
+ ```ts
188
+ registerGlobals({
189
+ before: [{ component: HeaderComponent, id: 'header' }],
190
+ after: [{ component: FooterComponent, id: 'footer' }],
191
+ });
192
+ ```
193
+
194
+ **Note**: `hideGlobals(globalIds: string[])` / `revealGlobals(globalIds: string[])` are exported alongside `registerGlobals` and can be called to toggle visibility of the ids you registered.
195
+
196
+ ## Testing
197
+
198
+ You can use any testing tool you prefer for application code.
199
+
200
+ This project includes TestinNutin, Nutin's lightweight testing toolkit. Nutin itself is tested exclusively with it, and the tests are included in the generated project so you can:
201
+ - use them as executable documentation;
202
+ - run and modify Nutin's tests when modifying its code.
203
+
204
+ Run the tests with:
205
+
206
+ `{{packageManager}} run testin-nutin`
207
+
208
+ To use TestinNutin for application tests, enable:
209
+
210
+ ```js
211
+ // nutin.config.js
212
+ testinNutin: {
213
+ includeApp: true,
214
+ }
215
+ ```
216
+ *Note:* TestinNutin files use root imports.
217
+ ```js
218
+ import { MyModule } from '#root/dist/src/path/to/my-module.js';
219
+ ```
220
+
221
+ See **[TestinNutin docs](https://nutin.org/docs/testin-nutin)**.
222
+
223
+ ## Useful links
224
+
225
+ - [Nutin website](https://www.nutin.org)
226
+ - [First app tutorial](https://www.nutin.org/tutorial)
227
+ - [Repository documentation](https://github.com/LoisKOUNINEF/nutin/tree/main/docs)
@@ -1,24 +1,15 @@
1
- # {{projectName}} - Built with nutin
1
+ # {{projectName}} - Built with Nutin
2
2
 
3
- ## Start
3
+ ## Development
4
4
 
5
- - `{{packageManager}} run serve` (rebuild), `{{packageManager}} run serve:only` (no rebuild), `{{packageManager}} run dev` (watch).
5
+ - `{{packageManager}} run serve` — build and serve
6
+ - `{{packageManager}} run dev` — build and serve with live reload
6
7
 
7
8
  ## Build
8
9
 
9
- - `{{packageManager}} run build` (dev) or `{{packageManager}} run build:prod` (production)
10
+ - `{{packageManager}} run build` — build the application
11
+ - `{{packageManager}} run build:prod` — build the application for production
10
12
 
11
- Accepts `--bundle` (= build:prod) and `--log` (verbose output) flags
13
+ ## Getting started
12
14
 
13
- ## Generate Component, View, Service
14
-
15
- - `{{packageManager}} run generate ELEMENT ELEMENT_NAME`
16
-
17
- Supports nested paths.
18
-
19
- {{#if testinNutin}}
20
- ## Test
21
-
22
- - `{{packageManager}} run test:rebuild`, `{{packageManager}} run test`, `{{packageManager}} run test:watch`.
23
-
24
- {{/if}}
15
+ See [Getting Started](GETTING_STARTED.md) for project-specific guidance.
@@ -0,0 +1,6 @@
1
+ {
2
+ "languages": [
3
+ "en"
4
+ ],
5
+ "defaultLanguage": "en"
6
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "baseUrl": "https://my-website.com",
3
+ "disallowBots": [],
4
+ "routes": [
5
+ {
6
+ "path": "/",
7
+ "title": "{{projectName}}",
8
+ "description": "{{projectName}}",
9
+ "ogImage": "/assets/images/og-cover.jpg"
10
+ }
11
+ ]
12
+ }
@@ -0,0 +1,51 @@
1
+ export default {
2
+ // Nutin options
3
+ tailwind: false, // Enable Tailwind CSS v4
4
+ i18n: false, // Enable i18n; configure languages in config/languages.json
5
+ generateSEOFiles: false, // Generate per-route HTML, robots.txt and sitemap.xml; configure SEO data in config/seo.json
6
+
7
+ // Components / Views scaffolding
8
+ generator: {
9
+ generateStylesheet: false, // Generate a .scss file alongside each component or view
10
+ generateLocales: false, // Generate locale files alongside components and views (requires i18n)
11
+ generateTest: false, // Generate test files alongside components, views and services (requires testinNutin.includeApp)
12
+ },
13
+
14
+ // Build pipeline
15
+ builder: {
16
+ sass: {
17
+ paths: [
18
+ 'base',
19
+ ], // Directories in styles/ to include in the Sass load path
20
+ },
21
+
22
+ esbuild: {
23
+ bundle: true,
24
+ minify: true,
25
+ sourcemap: false,
26
+ target: ['es2015'],
27
+ drop: ['console', 'debugger'],
28
+ },
29
+ },
30
+
31
+ // Testing toolkit
32
+ // `{{packageManager}} run testin-nutin`
33
+ testinNutin: {
34
+ includeFramework: true, // Test Nutin source - src/core
35
+ includeTools: false, // Test tools/ (builder, testin-nutin, etc.)
36
+ includeApp: false, // Include application tests
37
+
38
+ coverage: {
39
+ enabled: false, // Include coverage in the normal test command
40
+ threshold: 95, // Fail if any global coverage metric falls below this threshold
41
+ reportUncovered: true, // Generate a report of uncovered lines, functions and branches
42
+ },
43
+
44
+ jsdomOptions: {
45
+ runScripts: false,
46
+ resources: false,
47
+ freezeGlobals: false,
48
+ pretendToBeVisual: true,
49
+ },
50
+ },
51
+ }
@@ -1,2 +1 @@
1
- export * from './common/button/button.component.js';
2
- export * from './common/anchor/anchor.component.js';
1
+ // global components export
@@ -1,16 +1,4 @@
1
- declare type CoreEventMap = {
2
- 'navigate': string;
3
- 'reload': string;
4
- 'view-mount': string;
5
- 'view-render': string;
6
- 'view-unmount': string;
7
- 'track-pageview': { page: string };
8
-
9
- // Add other events and their payload types here
1
+ declare interface AppEventMap {
2
+ // Add app-specific event types here
3
+ // 'event': { /* payload? */ }
10
4
  };
11
-
12
- declare type StoreEventMap = {[ K in `store:${string}` ]: any; };
13
-
14
- // Merged event map
15
- declare type EventMap = CoreEventMap & StoreEventMap;
16
- declare type EventKey = keyof EventMap;
@@ -1,10 +1,6 @@
1
- import { RouteGuard } from "../../core/index.js";
1
+ import { RouteGuard } from "../core/index.js";
2
2
 
3
3
  export const Guards = {
4
- custom: (checkFn: () => boolean | string | Promise<boolean | string>, redirectTo?: string): RouteGuard => {
5
- return checkFn || redirectTo;
6
- },
7
-
8
4
  /**
9
5
  * Basic example
10
6
  */
@@ -1,39 +1,20 @@
1
- import { AppRouter, Service{{#if i18n}}, I18nService{{/if}} } from '../core/index.js';
2
- import { registerPipes } from '../libs/index.js';
1
+ import nutinConfig from '../../nutin.config.js';
2
+ import { AppRouter, Service, I18nService, registerPipes } from '../core/index.js';
3
3
  import { appRoutes } from './routes.js';
4
4
 
5
5
  class App {
6
- // private header: NavbarComponent;
7
-
8
6
  constructor() {
9
7
  registerPipes();
10
8
  AppRouter(appRoutes);
11
-
12
- // Init global components
13
- // this.header = new NavbarComponent('body' as unknown as HTMLElement);
14
- // this.footer = new FooterComponent('body' as unknown as HTMLElement);
15
-
16
- // Init app
17
- this.initialize();
18
- }
19
-
20
- public async initialize() {
21
- this.renderBaseLayout();
22
- }
23
-
24
- private renderBaseLayout() {
25
- // e
26
- // document.body.prepend(this.header.render());
27
- // document.body.append(this.footer.render());
28
9
  }
29
10
  }
30
11
 
31
12
  document.addEventListener('DOMContentLoaded', async () => {
32
- {{#if i18n}}
33
- await I18nService.initTranslations();
34
- await I18nService.loadTranslations(I18nService.currentLanguage);
35
- {{/if}}
36
- const app = new App();
13
+ if (nutinConfig.i18n) {
14
+ await I18nService.initTranslations();
15
+ await I18nService.loadTranslations(I18nService.currentLanguage);
16
+ }
17
+ new App();
37
18
  });
38
19
 
39
20
  window.addEventListener('beforeunload', async () => {
@@ -1 +1 @@
1
- export * from './example/example.service.js';
1
+ // global services export
@@ -0,0 +1,7 @@
1
+ <div style="display:flex;justify-content:center;align-items:center;flex-direction:column;padding-top:clamp(1rem,3vw,2rem);padding-bottom:clamp(1rem,3vw,2rem);">
2
+ <h1 style="color:#6C8359;font-size:clamp(1.5rem,5vw,2.5rem);font-weight:bold;">{{projectName}}</h1>
3
+ <span style="font-style:italic;font-size:clamp(.6875rem,2vw,1rem);">nutin v{{version}}</span>
4
+ <img src="/assets/images/logo-trans.avif" width=250 height=250 alt="nutin's logo. A frame opened on the top left through which a plant grows.">
5
+ <div style="color:#C56648;font-size:clamp(1.125rem,4vw,1.5rem);">Happy Coding 🎉</div>
6
+ <div style="font-size:clamp(.75rem,2vw,1rem);font-style:italic;position:fixed;bottom:0;">so lightweight it's <span style="font-weight:bold;">nutin</span>.</div>
7
+ </div>
@@ -1,61 +1,6 @@
1
1
  import { View } from '../../../core/index.js';
2
2
 
3
- const template = `{{#if template}}__TEMPLATE_PLACEHOLDER__{{else}}<div
4
- {{#if stylinNutin}}
5
- class="u-flex-center u-flex-column u-padd-y-large"
6
- {{else}}
7
- style="display:flex;justify-content:center;align-items:center;flex-direction:column;padding-top:1rem;padding-bottom: 1rem;"
8
- {{/if}}>
9
- <h1
10
- {{#if i18n}}
11
- data-i18n="home.title"
12
- {{/if}}
13
- {{#if stylinNutin}}
14
- class="u-color-prim u-font-largest u-bold u-font-secondary"
15
- style="color:#6C8359;"
16
- {{else}}
17
- style="color:#6C8359;font-size:2rem;font-weight:bold;"
18
- {{/if}}
19
- >{{#unless i18n}}{{projectName}}{{/unless}}</h1>
20
- <span
21
- {{#if stylinNutin}}
22
- class="u-italic u-font-smallest u-font-secondary"
23
- {{else}}
24
- style="font-style:italic;font-size:0.75rem;"
25
- {{/if}}
26
- >nutin v{{version}}</span>
27
- <img src="/assets/images/logo-trans.avif" width=250 height=250 alt="nutin's logo. A frame opened on the top left through which a plant grows.">
28
- <div
29
- {{#if i18n}}
30
- data-i18n="home.ready"
31
- {{/if}}
32
- {{#if stylinNutin}}
33
- class="u-font-large u-padd-y-medium"
34
- style="margin-top:-2rem;"
35
- {{else}}
36
- style="font-size:1.5rem;paddin-top:1rem;padding-bottom:1rem;margin-top:-2rem;"
37
- {{/if}}
38
- >{{#unless i18n}}You're all set !{{/unless}}</div>
39
- <div
40
- {{#if i18n}}
41
- data-i18n="home.enjoy"
42
- {{/if}}
43
- {{#if stylinNutin}}
44
- class="u-font-large u-color-sec"
45
- style="color:#C56648;"
46
- {{else}}
47
- style="color:#C56648;font-size:1.5rem;"
48
- {{/if}}
49
- >{{#unless i18n}}Happy Coding 🎉{{/unless}}</div>
50
- <div
51
- {{#if stylinNutin}}
52
- class="u-italic u-font-secondary u-font-small"
53
- {{#unless transition}}style="position:fixed;bottom:0;"{{/unless}}
54
- {{else}}
55
- style="font-size:.875rem;font-style:italic;{{#unless transition}}position:fixed;bottom:0;{{/unless}}"
56
- {{/if}}
57
- >so lightweight it's <span {{#if stylinNutin}}class="u-bold"{{else}}style="font-weight:bold;"{{/if}}>nutin</span>.</div>
58
- </div>{{/if}}`;
3
+ const template = `__TEMPLATE_PLACEHOLDER__`;
59
4
 
60
5
  export class HomeView extends View {
61
6
  constructor() {
@@ -1,2 +1,3 @@
1
+ // global views export
1
2
  export * from './home/home.view.js';
2
3
  export * from './not-found/not-found.view.js';
@@ -0,0 +1,8 @@
1
+ <div style="display:flex;justify-content:center;align-items:center;flex-direction:column;padding-top:clamp(1rem,5vw,2rem);">
2
+ <h1 style="font-size:clamp(2rem,8vw,3rem);font-weight:bold;">Page Not Found</h1>
3
+ <img src="/assets/images/logo-small-trans.avif" width=250 height=250 alt="nutin's small logo with a growing plant.">
4
+ <button
5
+ data-event="click:_handleHome"
6
+ style="background-color:inherit;font-size:clamp(1.25rem,5vw,2rem);font-style:italic;padding-top:clamp(.75rem,2vw,1rem);padding-bottom:clamp(.75rem,2vw,1rem);text-decoration:underline;"
7
+ >Go back</button>
8
+ </div>
@@ -1,46 +1,13 @@
1
- import { AppEventBus, ComponentConfig, View } from '../../../core/index.js';
2
- import { ButtonComponent } from '../../components/index.js';
1
+ import { Navigation, View } from '../../../core/index.js';
3
2
 
4
- const template = `{{#if template}}__TEMPLATE_PLACEHOLDER__{{else}}<div
5
- {{#if stylinNutin}}
6
- class="u-flex-center u-flex-column u-padd-y-large"
7
- {{else}}
8
- style="display:flex;justify-content:center;align-items:center;flex-direction:column"
9
- {{/if}}>
10
- <h1
11
- {{#if i18n}}
12
- data-i18n="not-found.content"
13
- {{/if}}
14
- {{#if stylinNutin}}
15
- class="u-color-sec u-font-largest u-bold u-font-secondary"
16
- {{else}}
17
- style="font-size:2rem;font-weight:bold;"
18
- {{/if}}
19
- >{{#unless i18n}}Page Not Found{{/unless}}</h1>
20
- <img src="/assets/images/logo-small-trans.avif" width=250 height=250 alt="nutin's small logo with a growing plant.">
21
- <div data-component="home"></div>
22
- </div>{{/if}}`;
3
+ const template = `__TEMPLATE_PLACEHOLDER__`;
23
4
 
24
5
  export class NotFoundView extends View {
25
6
  constructor() {
26
7
  super({template});
27
8
  }
28
9
 
29
- childConfigs(): ComponentConfig[] {
30
- {{#if stylinNutin}}
31
- const btnClass = 'u-bg-inherit u-font-large u-padd-y-medium u-color-prim u-italic';
32
- {{else}}
33
- const btnStyles = 'background-color:inherit;font-size:large;font-style:italic;padding-top:1rem;padding-bottom:1rem;'
34
- {{/if}}
35
- return [
36
- {
37
- selector: 'home',
38
- factory: (el) => new ButtonComponent(el, { {{#if i18n}}i18nKey: 'not-found.redirect'{{else}}textContent: 'Back to home'{{/if}}, callback: () => this.handleHome(), {{#if stylinNutin}}className: btnClass{{else}}style: btnStyles{{/if}} })
39
- },
40
- ]
41
- }
42
-
43
- handleHome() {
44
- AppEventBus.emit('navigate', '/');
10
+ private _handleHome(): void {
11
+ Navigation.navigateTo('/');
45
12
  }
46
13
  }