@nutin/cli 1.3.1 → 2.1.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 (289) hide show
  1. package/CHANGELOG.md +106 -9
  2. package/README.md +17 -35
  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 +76 -25
  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/{prompts.mjs → create-app/new-app-prompt.mjs} +6 -6
  22. package/lib/src/{project-generator.mjs → create-app/project-generator.mjs} +10 -8
  23. package/lib/src/create-app/success-message.mjs +13 -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 +142 -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 +168 -0
  36. package/templates/base/GETTING_STARTED.md.hbs +199 -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 +44 -0
  41. package/templates/base/src/app/components/index.ts.hbs +1 -2
  42. package/templates/base/src/app/globals.d.ts.hbs +3 -19
  43. package/templates/base/src/{libs/guards → app}/guards.ts.hbs +1 -5
  44. package/templates/base/src/app/main.ts.hbs +6 -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 +2 -57
  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 +5 -38
  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 +68 -35
  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 +9 -8
  55. package/templates/base/src/core/base-classes/base-component/helpers/children.helper.test.js.hbs +96 -0
  56. package/templates/base/src/core/base-classes/base-component/helpers/children.helper.ts.hbs +6 -3
  57. package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.test.js.hbs +151 -0
  58. package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.ts.hbs +8 -2
  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 +2 -2
  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 +89 -0
  63. package/templates/base/src/core/base-classes/base-component/helpers/pipe.helper.ts.hbs +4 -1
  64. package/templates/base/src/core/base-classes/base-component/helpers/security.helper.test.js.hbs +142 -0
  65. package/templates/base/src/core/base-classes/base-component/helpers/security.helper.ts.hbs +67 -22
  66. package/templates/base/src/core/base-classes/base-component/helpers/token.helper.test.js.hbs +183 -0
  67. package/templates/base/src/core/base-classes/component/component.test.js.hbs +85 -0
  68. package/templates/base/src/core/base-classes/component/component.ts.hbs +24 -33
  69. package/templates/base/src/core/base-classes/component/helpers/config.helper.test.js.hbs +58 -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 +71 -0
  74. package/templates/base/src/core/base-classes/view/view.ts.hbs +24 -49
  75. package/templates/base/src/core/config.ts.hbs +10 -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 +187 -0
  87. package/templates/base/src/core/services/globals/globals.ts.hbs +104 -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 +73 -2
  91. package/templates/base/src/core/services/http-client/http-client.ts.hbs +4 -1
  92. package/templates/base/src/core/services/i18n/i18n.test.js.hbs +270 -0
  93. package/templates/{features/i18n → base}/src/core/services/i18n/i18n.ts.hbs +22 -4
  94. package/templates/base/src/core/services/index.ts.hbs +5 -6
  95. package/templates/base/src/core/services/pipe-registry/pipe-registry.test.js.hbs +60 -1
  96. package/templates/base/src/core/services/pipe-registry/pipe-registry.ts.hbs +1 -1
  97. package/templates/base/src/core/services/pipe-registry/pipes.test.js.hbs +128 -0
  98. package/templates/base/src/{libs/pipes → core/services/pipe-registry}/pipes.ts.hbs +8 -5
  99. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.test.js.hbs +257 -6
  100. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.ts.hbs +56 -29
  101. package/templates/base/src/core/services/router/helpers/route-guard-manager.helper.test.js.hbs +27 -0
  102. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.test.js.hbs +83 -17
  103. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.ts.hbs +14 -38
  104. package/templates/base/src/core/services/router/router.test.js.hbs +304 -2
  105. package/templates/base/src/core/services/router/router.ts.hbs +47 -12
  106. package/templates/base/src/index.html.hbs +2 -6
  107. package/templates/base/src/styles/_styles.scss.hbs +102 -43
  108. package/templates/base/src/styles/base/_variables.scss.hbs +1 -86
  109. package/templates/base/src/styles/main.scss.hbs +1 -18
  110. package/templates/base/src/styles/tailwind.css.hbs +2 -0
  111. package/templates/base/tools/builder/builder.config.js.hbs +40 -0
  112. package/templates/base/tools/builder/builder.js.hbs +24 -26
  113. package/templates/base/tools/builder/core/app/binary-extensions.test.js.hbs +16 -0
  114. package/templates/base/tools/builder/core/app/compile-ts.js.hbs +16 -0
  115. package/templates/base/tools/builder/core/{copy-static.js.hbs → app/copy-static.js.hbs} +27 -34
  116. package/templates/base/tools/builder/core/app/validate-routes.js.hbs +77 -0
  117. package/templates/base/tools/builder/core/finalize-build.js.hbs +16 -7
  118. package/templates/base/tools/builder/core/{add-tags.js.hbs → html-index/add-tags.js.hbs} +2 -2
  119. package/templates/base/tools/builder/core/html-index/add-tags.test.js.hbs +56 -0
  120. package/templates/base/tools/builder/core/{validate-html.js.hbs → html-index/validate-html.js.hbs} +5 -11
  121. package/templates/base/tools/builder/core/html-templates/merge-templates.js.hbs +152 -0
  122. package/templates/base/tools/builder/core/html-templates/minify-html.js.hbs +15 -0
  123. package/templates/base/tools/builder/core/html-templates/process-html-templates.js.hbs +8 -0
  124. package/templates/{features/i18n/tools/builder/core → base/tools/builder/core/i18n}/build-i18n.js.hbs +6 -17
  125. package/templates/base/tools/builder/core/prod-bundle/compress-files.js.hbs +37 -0
  126. package/templates/base/tools/builder/core/prod-bundle/esbuild.js.hbs +30 -0
  127. package/templates/base/tools/builder/core/{hash-files.js.hbs → prod-bundle/hash-files.js.hbs} +14 -11
  128. package/templates/base/tools/builder/core/seo/generate-robots-txt.js.hbs +51 -0
  129. package/templates/base/tools/builder/core/seo/generate-seo-files.js.hbs +16 -0
  130. package/templates/base/tools/builder/core/seo/generate-seo-html.js.hbs +128 -0
  131. package/templates/base/tools/builder/core/seo/generate-sitemap-xml.js.hbs +43 -0
  132. package/templates/base/tools/builder/core/seo/html-substitutions.js.hbs +99 -0
  133. package/templates/base/tools/builder/core/seo/i18n-resolution.js.hbs +66 -0
  134. package/templates/base/tools/builder/core/seo/route-output.js.hbs +64 -0
  135. package/templates/base/tools/builder/core/seo/ssr/ssr-bundle.js.hbs +54 -0
  136. package/templates/base/tools/builder/core/seo/ssr/ssr-polyfills.js.hbs +132 -0
  137. package/templates/base/tools/builder/core/seo/ssr/ssr-render.js.hbs +95 -0
  138. package/templates/base/tools/builder/core/styles/sass.js.hbs +40 -0
  139. package/templates/base/tools/builder/core/styles/tailwind.js.hbs +84 -0
  140. package/templates/base/tools/dev/dev-serve.js.hbs +26 -18
  141. package/templates/base/tools/dev/serve.js.hbs +11 -1
  142. package/templates/base/tools/dev/watcher.js.hbs +14 -6
  143. package/templates/base/tools/generator/generator.js.hbs +44 -47
  144. package/templates/base/tools/generator/handle-file.js.hbs +17 -44
  145. package/templates/base/tools/generator/handle-file.test.js.hbs +72 -0
  146. package/templates/base/tools/generator/templates/{component.template.js.hbs → component/component.template.js.hbs} +3 -2
  147. package/templates/base/tools/generator/templates/component/component.template.test.js.hbs +23 -0
  148. package/templates/base/tools/generator/templates/html/html.template.js.hbs +2 -0
  149. package/templates/base/tools/generator/templates/html/html.template.test.js.hbs +7 -0
  150. package/templates/base/tools/generator/templates/index.js.hbs +7 -12
  151. package/templates/base/tools/generator/templates/locale/locale.template.js.hbs +8 -0
  152. package/templates/base/tools/generator/templates/locale/locale.template.test.js.hbs +17 -0
  153. package/templates/base/tools/generator/templates/scss/scss.template.js.hbs +1 -0
  154. package/templates/base/tools/generator/templates/scss/scss.template.test.js.hbs +7 -0
  155. package/templates/base/tools/generator/templates/service/service.template.js.hbs +17 -0
  156. package/templates/base/tools/generator/templates/service/service.template.test.js.hbs +22 -0
  157. package/templates/base/tools/generator/templates/test/test.template.js.hbs +10 -0
  158. package/templates/base/tools/generator/templates/test/test.template.test.js.hbs +27 -0
  159. package/templates/base/tools/generator/templates/{view.template.js.hbs → view/view.template.js.hbs} +4 -3
  160. package/templates/base/tools/generator/templates/view/view.template.test.js.hbs +24 -0
  161. package/templates/base/tools/testin-nutin/core/coverage/collect-coverage.js.hbs +39 -0
  162. package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.js.hbs +115 -0
  163. package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.test.js.hbs +74 -0
  164. package/templates/base/tools/testin-nutin/core/coverage/write-summary-report.js.hbs +54 -0
  165. package/templates/base/tools/testin-nutin/core/coverage/write-uncovered-report.js.hbs +44 -0
  166. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/assertion-lib.js.hbs +62 -24
  167. package/templates/base/tools/testin-nutin/core/globals/clock.js.hbs +206 -0
  168. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/jsdom-setup.js.hbs +19 -6
  169. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/register-test-globals.js.hbs +13 -4
  170. package/templates/base/tools/testin-nutin/core/globals/silence-console.js.hbs +23 -0
  171. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/spyon.js.hbs +2 -0
  172. package/templates/base/tools/testin-nutin/core/index.js.hbs +9 -0
  173. package/templates/base/tools/testin-nutin/core/printer.js.hbs +85 -0
  174. package/templates/base/tools/testin-nutin/core/queue/queue.test.js.hbs +46 -0
  175. package/templates/base/tools/testin-nutin/core/queue/test-discovery.test.js.hbs +46 -0
  176. package/templates/base/tools/testin-nutin/core/queue/test-queue.js.hbs +154 -0
  177. package/templates/{features/testinNutin → base/tools}/testin-nutin/core/tests/assertions.test.js.hbs +27 -0
  178. package/templates/base/tools/testin-nutin/core/tests/clock.test.js.hbs +118 -0
  179. package/templates/base/tools/testin-nutin/core/tests/globals-each-all.test.js.hbs +28 -0
  180. package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/create-mock-method.js.hbs +2 -1
  181. package/templates/base/tools/testin-nutin/mocks/create-mock-method.test.js.hbs +64 -0
  182. package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-event-bus.js.hbs +3 -2
  183. package/templates/base/tools/testin-nutin/mocks/mock-event-bus.test.js.hbs +66 -0
  184. package/templates/base/tools/testin-nutin/mocks/mock-http-client.test.js.hbs +26 -0
  185. package/templates/base/tools/testin-nutin/mocks/mock-i18n.test.js.hbs +61 -0
  186. package/templates/base/tools/testin-nutin/mocks/mock-router.test.js.hbs +29 -0
  187. package/templates/base/tools/testin-nutin/runner.js.hbs +100 -0
  188. package/templates/base/tools/testin-nutin/watch-tests.js.hbs +37 -0
  189. package/templates/base/tools/utils/error-exit.js.hbs +8 -0
  190. package/templates/base/tools/utils/format.js.hbs +10 -10
  191. package/templates/base/tools/utils/format.test.js.hbs +45 -0
  192. package/templates/base/tools/utils/get-files-recursive.js.hbs +6 -1
  193. package/templates/base/tools/utils/get-files-recursive.test.js.hbs +49 -0
  194. package/templates/base/tools/utils/get-rel-to-core.test.js.hbs +18 -0
  195. package/templates/base/tools/utils/index.js.hbs +1 -3
  196. package/templates/base/tools/utils/languages.js.hbs +15 -0
  197. package/templates/base/tools/utils/languages.test.js.hbs +16 -0
  198. package/templates/base/tools/utils/print.js.hbs +19 -13
  199. package/templates/base/tools/utils/print.test.js.hbs +60 -0
  200. package/templates/base/tools/utils/prompt-boolean.js.hbs +7 -0
  201. package/templates/base/tools/utils/prompt-boolean.test.js.hbs +54 -0
  202. package/templates/base/tools/utils/run-command.js.hbs +4 -2
  203. package/templates/base/tools/utils/run-command.test.js.hbs +19 -0
  204. package/templates/base/tools/utils/run-script.js.hbs +14 -3
  205. package/templates/base/tools/utils/run-script.test.js.hbs +40 -0
  206. package/templates/features/{deployHelper → docker}/.dockerignore.hbs +4 -4
  207. package/templates/features/docker/tools/docker/Dockerfile.template.hbs +51 -0
  208. package/templates/features/{deployHelper/tools/deployment/nginx.conf.hbs → docker/tools/docker/nginx.conf.template} +4 -2
  209. package/templates/features/docker/tools/docker/scripts/docker-build.js.hbs +20 -0
  210. package/templates/features/docker/tools/docker/scripts/docker-ports.js.hbs +48 -0
  211. package/templates/features/docker/tools/docker/scripts/docker-ports.test.js.hbs +52 -0
  212. package/templates/features/docker/tools/docker/scripts/docker-run.js.hbs +28 -0
  213. package/templates/features/docker/tools/docker/scripts/render-docker-template.js.hbs +23 -0
  214. package/templates/features/docker/tools/docker/scripts/render-docker-template.test.js.hbs +60 -0
  215. package/templates/features/docker/tools/docker/scripts/validate-docker.js.hbs +30 -0
  216. package/lib/src/context-builder.mjs +0 -40
  217. package/lib/src/file-generator.mjs +0 -109
  218. package/lib/src/json-generator.mjs +0 -31
  219. package/lib/src/package-manager.mjs +0 -139
  220. package/lib/src/print.mjs +0 -32
  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 -36
  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 -113
  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 -131
  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/helpers/focus-trap.helper.ts.hbs +0 -197
  239. package/templates/base/src/libs/popover/helpers/popover-dom.helper.ts.hbs +0 -75
  240. package/templates/base/src/libs/popover/popover.ts.hbs +0 -138
  241. package/templates/base/src/libs/snackbar/snackbar.ts.hbs +0 -75
  242. package/templates/base/src/styles/base/_functions.scss.hbs +0 -9
  243. package/templates/base/src/styles/core/_anchors.scss.hbs +0 -10
  244. package/templates/base/src/styles/core/_index.scss.hbs +0 -6
  245. package/templates/base/src/styles/core/_popover.scss.hbs +0 -96
  246. package/templates/base/src/styles/core/_snackbar.scss.hbs +0 -50
  247. package/templates/base/tools/builder/core/esbuild.js.hbs +0 -25
  248. package/templates/base/tools/builder/core/minify-html.js.hbs +0 -60
  249. package/templates/base/tools/builder/core/sass.js.hbs +0 -22
  250. package/templates/base/tools/builder/core/tsc.js.hbs +0 -12
  251. package/templates/base/tools/generator/templates/service.template.js.hbs +0 -17
  252. package/templates/base/tools/utils/export-flags.js.hbs +0 -6
  253. package/templates/features/deployHelper/tools/builder/core/compress-files.js.hbs +0 -56
  254. package/templates/features/deployHelper/tools/deployment/Dockerfile.hbs +0 -30
  255. package/templates/features/i18n/src/app/views/home/locales/en.json.hbs +0 -9
  256. package/templates/features/i18n/src/app/views/not-found/locales/en.json +0 -8
  257. package/templates/features/i18n/src/app/views/not-found/locales/fr.json +0 -8
  258. package/templates/features/i18n/src/core/config.ts.hbs +0 -3
  259. package/templates/features/i18n/src/core/services/i18n/i18n.test.js.hbs +0 -125
  260. package/templates/features/i18n/tools/generator/templates/json.template.js.hbs +0 -8
  261. package/templates/features/i18n/tools/utils/languages.js.hbs +0 -7
  262. package/templates/features/stylinNutin/src/styles/_custom-classes.scss.hbs +0 -9
  263. package/templates/features/stylinNutin/src/styles/base/_mixins.scss.hbs +0 -372
  264. package/templates/features/stylinNutin/src/styles/components/_index.scss.hbs +0 -3
  265. package/templates/features/stylinNutin/src/styles/core/_utilities.scss.hbs +0 -254
  266. package/templates/features/stylinNutin/src/styles/views/_index.scss.hbs +0 -0
  267. package/templates/features/stylinNutin/tools/generator/templates/scss.template.js.hbs +0 -4
  268. package/templates/features/template/src/app/views/home/home.view.html.hbs +0 -56
  269. package/templates/features/template/src/app/views/not-found/not-found.view.html.hbs +0 -19
  270. package/templates/features/template/tools/builder/core/merge-templates.js.hbs +0 -49
  271. package/templates/features/template/tools/generator/templates/html.template.js.hbs +0 -2
  272. package/templates/features/testinNutin/testin-nutin/core/index.js.hbs +0 -5
  273. package/templates/features/testinNutin/testin-nutin/core/src/utils/print.js.hbs +0 -64
  274. package/templates/features/testinNutin/testin-nutin/core/src/utils/test-queue.js.hbs +0 -64
  275. package/templates/features/testinNutin/testin-nutin/core/tests/globals-each-all.test.js.hbs +0 -28
  276. package/templates/features/testinNutin/testin-nutin/mocks/mock-store.js.hbs +0 -38
  277. package/templates/features/testinNutin/testin-nutin/runner.js.hbs +0 -36
  278. package/templates/features/testinNutin/testin-nutin/watch-tests.js.hbs +0 -21
  279. package/templates/features/testinNutin/testin-nutin.config.js.hbs +0 -14
  280. /package/lib/src/{template-compiler.mjs → common/template-compiler.mjs} +0 -0
  281. /package/templates/{features/i18n → base}/src/core/base-classes/base-component/helpers/i18n.helper.ts.hbs +0 -0
  282. /package/templates/{features/i18n → base}/src/core/services/i18n/languages.ts.hbs +0 -0
  283. /package/templates/base/tools/builder/{variables → core/app}/binary-extensions.js.hbs +0 -0
  284. /package/templates/base/tools/builder/core/{paths.js.hbs → app/paths.js.hbs} +0 -0
  285. /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/queue.js.hbs +0 -0
  286. /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/test-discovery.js.hbs +0 -0
  287. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-http-client.js.hbs +0 -0
  288. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-i18n.js.hbs +0 -0
  289. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-router.js.hbs +0 -0
@@ -0,0 +1,199 @@
1
+ # Getting started
2
+
3
+ ## Table of contents
4
+
5
+ - [Project structure](#project-structure)
6
+ - [How do I run my app?](#running-your-app)
7
+ - [How do I generate components, views and services?](#generate-components-views-and-services)
8
+ - [What does a typical component look like?](#a-typical-component)
9
+ - [Options and configuration](#options-and-configuration)
10
+ - [Styling](#styling)
11
+ - [Testing](#testing)
12
+ - [Go further](#go-further)
13
+
14
+ ## Project structure
15
+
16
+ ```
17
+ src/
18
+ app/
19
+ components/
20
+ services/
21
+ views/
22
+ routes.ts
23
+ main.ts
24
+ assets/
25
+ core/ -- Nutin framework source
26
+ styles/
27
+
28
+ tools/ -- build, development, generator and testing
29
+
30
+ nutin.config.js -- features and configuration
31
+ ```
32
+
33
+ ### Imports
34
+
35
+ Imports use **relative paths** and end with `.js` extension.
36
+
37
+ ```js
38
+ import { Foo } from 'relative/path/to/foo.js';
39
+ ```
40
+
41
+ ## How do I run my app?
42
+
43
+ ```bash
44
+ # Development
45
+ {{packageManager}} run serve # build and serve
46
+ {{packageManager}} run dev # build and serve with live reload
47
+
48
+ # Build
49
+ {{packageManager}} run build # build the application
50
+ {{packageManager}} run build:prod # build the application for production
51
+ ```
52
+
53
+ ## How do I generate components, views and services?
54
+
55
+ Generated elements are automatically exported from the corresponding barrel file:
56
+ `src/app/<components|views|services>/index.ts`.
57
+
58
+
59
+ ```bash
60
+ {{packageManager}} run generate <component|view|service> ELEMENT_NAME
61
+
62
+ # Examples
63
+ {{packageManager}} run generate component my-component # Target dir: src/app/components/my-component/
64
+ {{packageManager}} run generate component path/to/my-component/ # Target dir: src/app/components/path/to/my-component/
65
+ ```
66
+
67
+ ## What does a typical component look like?
68
+
69
+ ```bash
70
+ components/
71
+ product-card/
72
+ product-card.component.html
73
+ product-card.component.scss
74
+ product-card.component.ts
75
+ ```
76
+
77
+ ```ts
78
+ // The builder injects the component's .html template here.
79
+ const templateFn = (product: Product) => `__TEMPLATE_PLACEHOLDER__`;
80
+
81
+ export class ProductCardComponent extends Component {
82
+ private _product: Product;
83
+
84
+ constructor(mountTarget: HTMLElement, config: Product) {
85
+ super({ templateFn, mountTarget, config });
86
+ this._product = config;
87
+ }
88
+
89
+ // Declares children mounted into the data-component / data-catalog placeholders below.
90
+ public registerChildren(): ComponentConfig[] {
91
+ // Single child, matched to <div data-component="product-details">
92
+ const detailsComponent = {
93
+ selector: `product-details`,
94
+ factory: (el) => new ProductDetailsComponent(
95
+ el,
96
+ { config: this._product.details },
97
+ )
98
+ };
99
+
100
+ // One child per item in _product.tags, matched to <div data-catalog="product-tags">
101
+ const tagsCatalog = this.createCatalogComponents({
102
+ selector: 'product-tags',
103
+ items: this._product.tags,
104
+ component: ProductTagsComponent,
105
+ elementName: 'product-tag'
106
+ });
107
+
108
+ return [
109
+ detailsComponent,
110
+ ...tagsCatalog
111
+ ];
112
+ }
113
+
114
+ // Referenced by the data-event attribute in the template.
115
+ private _goToProductPage(productId: string): void {
116
+ Navigation.navigateTo(`/product/${productId}`);
117
+ }
118
+ }
119
+ ```
120
+
121
+ ```html
122
+ <div
123
+ data-event="click:_goToProductPage:${product.id}"
124
+ class="product-card"
125
+ >
126
+ <h2 class="product-card__name">${product.name}</h2>
127
+ <div data-component="product-details"></div>
128
+ <div data-catalog="product-tags"></div>
129
+ </div>
130
+ ```
131
+
132
+ ```scss
133
+ .product-card {
134
+ // component styles
135
+ }
136
+
137
+ .product-card__name {
138
+ // element styles
139
+ }
140
+ ```
141
+
142
+ A template can also be written directly inline (skip the `.html` file and the placeholder).
143
+
144
+ Defining both an inline template and an external `.html` file, or neither, fails the build.
145
+
146
+ ## Options and configuration
147
+
148
+ ### Main file
149
+
150
+ `nutin.config.js` - Main Nutin configuration and tool options. See the inline comments for details.
151
+
152
+ - `tailwind`, `i18n`, `generateSEOFiles` — top-level features, `false` by default.
153
+ See [Options and features](https://github.com/LoisKOUNINEF/nutin/tree/main/docs/OPTIONS_AND_FEATURES.md).
154
+ - `builder.*` — controls build behavior.
155
+ - `testinNutin.*` — controls Nutin's built-in testing toolkit.
156
+
157
+ ### Specialized files
158
+
159
+ - `config/seo.json` - with `generateSEOFiles` enabled. Register your routes' description, title and ogImage here.
160
+ - `config/languages.json` - with `i18n` enabled. Register supported languages here.
161
+
162
+ ## Styling
163
+
164
+ - Nutin uses SASS (`.scss` syntax, compatible with plain CSS) as its default styling solution.
165
+
166
+ - Tailwind CSS v4 is also supported as an optional utility-first CSS layer.
167
+
168
+ **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.
169
+
170
+ ## Testing
171
+
172
+ You can use any testing tool you prefer for application code.
173
+
174
+ This project includes [testin-nutin](https://github.com/LoisKOUNINEF/nutin/tree/main/docs/TESTING.md), Nutin's lightweight testing toolkit. Nutin itself is tested exclusively with it, and the tests are included in the generated project so you can:
175
+ - use them as executable documentation;
176
+ - run and modify Nutin's tests when modifying its code.
177
+
178
+ Run the tests with:
179
+
180
+ `{{packageManager}} run testin-nutin`
181
+
182
+ To use testin-nutin for application tests, enable:
183
+
184
+ ```js
185
+ // nutin.config.js
186
+ testinNutin: {
187
+ includeApp: true,
188
+ }
189
+ ```
190
+ *Note:* TestinNutin files use root imports.
191
+ ```js
192
+ import { MyModule } from '#root/dist/src/path/to/my-module.js';
193
+ ```
194
+
195
+ ## Go further
196
+
197
+ - [Repository documentation](https://github.com/LoisKOUNINEF/nutin/tree/main/docs/API.md)
198
+ - [First app tutorial](https://www.nutin.org/tutorial)
199
+ - [Nutin website](https://www.nutin.org)
@@ -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,44 @@
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
+ // Build pipeline
8
+ builder: {
9
+ sass: {
10
+ paths: [
11
+ 'base',
12
+ ], // Directories in styles/ to include in the Sass load path
13
+ },
14
+
15
+ esbuild: {
16
+ bundle: true,
17
+ minify: true,
18
+ sourcemap: false,
19
+ target: ['es2015'],
20
+ drop: ['console', 'debugger'],
21
+ },
22
+ },
23
+
24
+ // Testing toolkit
25
+ // `{{packageManager}} run testin-nutin`
26
+ testinNutin: {
27
+ includeFramework: true, // Test Nutin source - src/core
28
+ includeTools: false, // Test tools/ (builder, testin-nutin, etc.)
29
+ includeApp: false, // Include application tests
30
+
31
+ coverage: {
32
+ enabled: false, // Include coverage in the normal test command
33
+ threshold: 95, // Fail if any global coverage metric falls below this threshold
34
+ reportUncovered: true, // Generate a report of uncovered lines, functions and branches
35
+ },
36
+
37
+ jsdomOptions: {
38
+ runScripts: false,
39
+ resources: false,
40
+ freezeGlobals: false,
41
+ pretendToBeVisual: true,
42
+ },
43
+ },
44
+ }
@@ -1,2 +1 @@
1
- export * from './common/button/button.component.js';
2
- export * from './common/anchor/anchor.component.js';
1
+ // global components export
@@ -1,20 +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
- 'popover-opened': string;
9
- 'popover-close': string;
10
- {{#if i18n}}
11
- 'language-changed': string;
12
- {{/if}}
13
- // Add other events and their payload types here
1
+ declare interface AppEventMap {
2
+ // Add app-specific event types here
3
+ // 'event': { /* payload? */ }
14
4
  };
15
-
16
- declare type StoreEventMap = {[ K in `store:${string}` ]: any; };
17
-
18
- // Merged event map
19
- declare type EventMap = CoreEventMap & StoreEventMap;
20
- 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,19 @@
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
+ }
16
+ new App();
37
17
  });
38
18
 
39
19
  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,64 +1,9 @@
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() {
62
- super({template});
7
+ super({ template, viewName: 'home' });
63
8
  }
64
9
  }
@@ -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
- super({template});
7
+ super({ template, viewName: 'not-found' });
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
  }