@nutin/cli 1.3.1 → 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 (287) hide show
  1. package/CHANGELOG.md +89 -9
  2. package/README.md +20 -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 +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 -19
  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 +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 +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 +7 -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 +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 +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 +24 -33
  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/data-binding.helper.test.js.hbs +75 -0
  70. package/templates/base/src/core/base-classes/service/service.test.js.hbs +150 -0
  71. package/templates/base/src/core/base-classes/service/service.ts.hbs +26 -20
  72. package/templates/base/src/core/base-classes/view/view.test.js.hbs +74 -0
  73. package/templates/base/src/core/base-classes/view/view.ts.hbs +17 -41
  74. package/templates/base/src/core/config.ts.hbs +7 -0
  75. package/templates/base/src/core/index.ts.hbs +0 -3
  76. package/templates/base/src/core/internals.d.ts.hbs +27 -0
  77. package/templates/base/src/core/nutin-config.d.ts.hbs +4 -0
  78. package/templates/base/src/core/services/event-bus/event-bus.test.js.hbs +67 -3
  79. package/templates/base/src/core/services/event-bus/event-bus.ts.hbs +9 -4
  80. package/templates/base/src/core/services/event-bus/index.ts.hbs +3 -0
  81. package/templates/base/src/core/services/event-bus/lifecycle.facade.test.js.hbs +123 -0
  82. package/templates/base/src/core/services/event-bus/lifecycle.facade.ts.hbs +61 -0
  83. package/templates/base/src/core/services/event-bus/navigation.facade.test.js.hbs +46 -0
  84. package/templates/base/src/core/services/event-bus/navigation.facade.ts.hbs +25 -0
  85. package/templates/base/src/core/services/globals/globals.test.js.hbs +149 -0
  86. package/templates/base/src/core/services/globals/globals.ts.hbs +95 -0
  87. package/templates/base/src/core/services/http-client/helpers/http-builder.helper.test.js.hbs +25 -0
  88. package/templates/base/src/core/services/http-client/helpers/http-manager.helper.test.js.hbs +20 -0
  89. package/templates/base/src/core/services/http-client/http-client.test.js.hbs +43 -0
  90. package/templates/base/src/core/services/i18n/i18n.test.js.hbs +270 -0
  91. package/templates/{features/i18n → base}/src/core/services/i18n/i18n.ts.hbs +22 -4
  92. package/templates/base/src/core/services/index.ts.hbs +5 -6
  93. package/templates/base/src/core/services/pipe-registry/pipe-registry.test.js.hbs +60 -1
  94. package/templates/base/src/core/services/pipe-registry/pipe-registry.ts.hbs +1 -1
  95. package/templates/base/src/core/services/pipe-registry/pipes.test.js.hbs +128 -0
  96. package/templates/base/src/{libs/pipes → core/services/pipe-registry}/pipes.ts.hbs +8 -5
  97. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.test.js.hbs +149 -6
  98. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.ts.hbs +40 -29
  99. package/templates/base/src/core/services/router/helpers/route-guard-manager.helper.test.js.hbs +27 -0
  100. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.test.js.hbs +83 -17
  101. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.ts.hbs +14 -38
  102. package/templates/base/src/core/services/router/router.test.js.hbs +226 -2
  103. package/templates/base/src/core/services/router/router.ts.hbs +40 -8
  104. package/templates/base/src/index.html.hbs +2 -6
  105. package/templates/base/src/styles/_styles.scss.hbs +102 -43
  106. package/templates/base/src/styles/base/_variables.scss.hbs +1 -86
  107. package/templates/base/src/styles/main.scss.hbs +1 -18
  108. package/templates/base/src/styles/tailwind.css.hbs +2 -0
  109. package/templates/base/tools/builder/builder.config.js.hbs +40 -0
  110. package/templates/base/tools/builder/builder.js.hbs +24 -26
  111. package/templates/base/tools/builder/core/app/binary-extensions.test.js.hbs +16 -0
  112. package/templates/base/tools/builder/core/app/compile-ts.js.hbs +16 -0
  113. package/templates/base/tools/builder/core/{copy-static.js.hbs → app/copy-static.js.hbs} +27 -34
  114. package/templates/base/tools/builder/core/app/validate-routes.js.hbs +77 -0
  115. package/templates/base/tools/builder/core/finalize-build.js.hbs +16 -7
  116. package/templates/base/tools/builder/core/{add-tags.js.hbs → html-index/add-tags.js.hbs} +2 -2
  117. package/templates/base/tools/builder/core/html-index/add-tags.test.js.hbs +56 -0
  118. package/templates/base/tools/builder/core/{validate-html.js.hbs → html-index/validate-html.js.hbs} +5 -11
  119. package/templates/base/tools/builder/core/html-templates/merge-templates.js.hbs +152 -0
  120. package/templates/base/tools/builder/core/html-templates/minify-html.js.hbs +15 -0
  121. package/templates/base/tools/builder/core/html-templates/process-html-templates.js.hbs +8 -0
  122. package/templates/{features/i18n/tools/builder/core → base/tools/builder/core/i18n}/build-i18n.js.hbs +6 -17
  123. package/templates/base/tools/builder/core/prod-bundle/compress-files.js.hbs +37 -0
  124. package/templates/base/tools/builder/core/prod-bundle/esbuild.js.hbs +30 -0
  125. package/templates/base/tools/builder/core/{hash-files.js.hbs → prod-bundle/hash-files.js.hbs} +14 -11
  126. package/templates/base/tools/builder/core/seo/generate-robots-txt.js.hbs +51 -0
  127. package/templates/base/tools/builder/core/seo/generate-seo-files.js.hbs +16 -0
  128. package/templates/base/tools/builder/core/seo/generate-seo-html.js.hbs +128 -0
  129. package/templates/base/tools/builder/core/seo/generate-sitemap-xml.js.hbs +43 -0
  130. package/templates/base/tools/builder/core/seo/html-substitutions.js.hbs +99 -0
  131. package/templates/base/tools/builder/core/seo/i18n-resolution.js.hbs +66 -0
  132. package/templates/base/tools/builder/core/seo/route-output.js.hbs +64 -0
  133. package/templates/base/tools/builder/core/seo/ssr/ssr-bundle.js.hbs +54 -0
  134. package/templates/base/tools/builder/core/seo/ssr/ssr-polyfills.js.hbs +132 -0
  135. package/templates/base/tools/builder/core/seo/ssr/ssr-render.js.hbs +95 -0
  136. package/templates/base/tools/builder/core/styles/sass.js.hbs +40 -0
  137. package/templates/base/tools/builder/core/styles/tailwind.js.hbs +84 -0
  138. package/templates/base/tools/dev/dev-serve.js.hbs +26 -18
  139. package/templates/base/tools/dev/serve.js.hbs +11 -1
  140. package/templates/base/tools/dev/watcher.js.hbs +14 -6
  141. package/templates/base/tools/generator/generator.js.hbs +64 -47
  142. package/templates/base/tools/generator/handle-file.js.hbs +17 -44
  143. package/templates/base/tools/generator/handle-file.test.js.hbs +72 -0
  144. package/templates/base/tools/generator/templates/{component.template.js.hbs → component/component.template.js.hbs} +3 -2
  145. package/templates/base/tools/generator/templates/component/component.template.test.js.hbs +23 -0
  146. package/templates/base/tools/generator/templates/html/html.template.js.hbs +2 -0
  147. package/templates/base/tools/generator/templates/html/html.template.test.js.hbs +7 -0
  148. package/templates/base/tools/generator/templates/index.js.hbs +7 -12
  149. package/templates/base/tools/generator/templates/locale/locale.template.js.hbs +4 -0
  150. package/templates/base/tools/generator/templates/locale/locale.template.test.js.hbs +7 -0
  151. package/templates/base/tools/generator/templates/scss/scss.template.js.hbs +1 -0
  152. package/templates/base/tools/generator/templates/scss/scss.template.test.js.hbs +7 -0
  153. package/templates/base/tools/generator/templates/service/service.template.js.hbs +17 -0
  154. package/templates/base/tools/generator/templates/service/service.template.test.js.hbs +22 -0
  155. package/templates/base/tools/generator/templates/test/test.template.js.hbs +10 -0
  156. package/templates/base/tools/generator/templates/test/test.template.test.js.hbs +27 -0
  157. package/templates/base/tools/generator/templates/{view.template.js.hbs → view/view.template.js.hbs} +3 -2
  158. package/templates/base/tools/generator/templates/view/view.template.test.js.hbs +24 -0
  159. package/templates/base/tools/testin-nutin/core/coverage/collect-coverage.js.hbs +39 -0
  160. package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.js.hbs +115 -0
  161. package/templates/base/tools/testin-nutin/core/coverage/compute-coverage.test.js.hbs +74 -0
  162. package/templates/base/tools/testin-nutin/core/coverage/write-summary-report.js.hbs +54 -0
  163. package/templates/base/tools/testin-nutin/core/coverage/write-uncovered-report.js.hbs +44 -0
  164. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/assertion-lib.js.hbs +62 -24
  165. package/templates/base/tools/testin-nutin/core/globals/clock.js.hbs +206 -0
  166. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/jsdom-setup.js.hbs +19 -6
  167. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/register-test-globals.js.hbs +13 -4
  168. package/templates/base/tools/testin-nutin/core/globals/silence-console.js.hbs +23 -0
  169. package/templates/{features/testinNutin/testin-nutin/core/src → base/tools/testin-nutin/core}/globals/spyon.js.hbs +2 -0
  170. package/templates/base/tools/testin-nutin/core/index.js.hbs +9 -0
  171. package/templates/base/tools/testin-nutin/core/printer.js.hbs +85 -0
  172. package/templates/base/tools/testin-nutin/core/queue/queue.test.js.hbs +46 -0
  173. package/templates/base/tools/testin-nutin/core/queue/test-discovery.test.js.hbs +46 -0
  174. package/templates/base/tools/testin-nutin/core/queue/test-queue.js.hbs +154 -0
  175. package/templates/{features/testinNutin → base/tools}/testin-nutin/core/tests/assertions.test.js.hbs +27 -0
  176. package/templates/base/tools/testin-nutin/core/tests/clock.test.js.hbs +118 -0
  177. package/templates/base/tools/testin-nutin/core/tests/globals-each-all.test.js.hbs +28 -0
  178. package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/create-mock-method.js.hbs +2 -1
  179. package/templates/base/tools/testin-nutin/mocks/create-mock-method.test.js.hbs +64 -0
  180. package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-event-bus.js.hbs +3 -2
  181. package/templates/base/tools/testin-nutin/mocks/mock-event-bus.test.js.hbs +66 -0
  182. package/templates/base/tools/testin-nutin/mocks/mock-http-client.test.js.hbs +26 -0
  183. package/templates/base/tools/testin-nutin/mocks/mock-i18n.test.js.hbs +61 -0
  184. package/templates/base/tools/testin-nutin/mocks/mock-router.test.js.hbs +29 -0
  185. package/templates/base/tools/testin-nutin/runner.js.hbs +100 -0
  186. package/templates/base/tools/testin-nutin/watch-tests.js.hbs +37 -0
  187. package/templates/base/tools/utils/error-exit.js.hbs +8 -0
  188. package/templates/base/tools/utils/format.js.hbs +10 -10
  189. package/templates/base/tools/utils/format.test.js.hbs +45 -0
  190. package/templates/base/tools/utils/get-files-recursive.js.hbs +6 -1
  191. package/templates/base/tools/utils/get-files-recursive.test.js.hbs +49 -0
  192. package/templates/base/tools/utils/get-rel-to-core.test.js.hbs +18 -0
  193. package/templates/base/tools/utils/index.js.hbs +1 -3
  194. package/templates/base/tools/utils/languages.js.hbs +15 -0
  195. package/templates/base/tools/utils/languages.test.js.hbs +16 -0
  196. package/templates/base/tools/utils/print.js.hbs +19 -13
  197. package/templates/base/tools/utils/print.test.js.hbs +60 -0
  198. package/templates/base/tools/utils/prompt-boolean.js.hbs +7 -0
  199. package/templates/base/tools/utils/prompt-boolean.test.js.hbs +54 -0
  200. package/templates/base/tools/utils/run-command.js.hbs +4 -2
  201. package/templates/base/tools/utils/run-command.test.js.hbs +19 -0
  202. package/templates/base/tools/utils/run-script.js.hbs +14 -3
  203. package/templates/base/tools/utils/run-script.test.js.hbs +40 -0
  204. package/templates/features/{deployHelper → docker}/.dockerignore.hbs +4 -4
  205. package/templates/features/docker/tools/docker/Dockerfile.template.hbs +51 -0
  206. package/templates/features/{deployHelper/tools/deployment/nginx.conf.hbs → docker/tools/docker/nginx.conf.template} +4 -2
  207. package/templates/features/docker/tools/docker/scripts/docker-build.js.hbs +20 -0
  208. package/templates/features/docker/tools/docker/scripts/docker-ports.js.hbs +48 -0
  209. package/templates/features/docker/tools/docker/scripts/docker-ports.test.js.hbs +52 -0
  210. package/templates/features/docker/tools/docker/scripts/docker-run.js.hbs +28 -0
  211. package/templates/features/docker/tools/docker/scripts/render-docker-template.js.hbs +23 -0
  212. package/templates/features/docker/tools/docker/scripts/render-docker-template.test.js.hbs +60 -0
  213. package/templates/features/docker/tools/docker/scripts/validate-docker.js.hbs +30 -0
  214. package/lib/src/context-builder.mjs +0 -40
  215. package/lib/src/file-generator.mjs +0 -109
  216. package/lib/src/json-generator.mjs +0 -31
  217. package/lib/src/package-manager.mjs +0 -139
  218. package/lib/src/print.mjs +0 -32
  219. package/lib/src/utils.mjs +0 -18
  220. package/lib/src/version.mjs +0 -1
  221. package/templates/base/builder.config.js.hbs +0 -36
  222. package/templates/base/src/app/components/common/anchor/anchor.component.ts.hbs +0 -32
  223. package/templates/base/src/app/components/common/button/button.component.ts.hbs +0 -40
  224. package/templates/base/src/app/dom.test.js.hbs +0 -13
  225. package/templates/base/src/app/services/example/example.service.ts.hbs +0 -18
  226. package/templates/base/src/app/views/home/home.view.test.js.hbs +0 -26
  227. package/templates/base/src/core/services/store/store.test.js.hbs +0 -8
  228. package/templates/base/src/core/services/store/store.ts.hbs +0 -39
  229. package/templates/base/src/core/utils/anchor-manager/anchor-manager.utils.test.js.hbs +0 -0
  230. package/templates/base/src/core/utils/anchor-manager/anchor-manager.utils.ts.hbs +0 -113
  231. package/templates/base/src/core/utils/button-manager/button-manager.utils.test.js.hbs +0 -249
  232. package/templates/base/src/core/utils/button-manager/button-manager.utils.ts.hbs +0 -131
  233. package/templates/base/src/core/utils/helpers/attributes.helper.ts.hbs +0 -50
  234. package/templates/base/src/core/utils/index.ts.hbs +0 -2
  235. package/templates/base/src/libs/index.ts.hbs +0 -4
  236. package/templates/base/src/libs/popover/helpers/focus-trap.helper.ts.hbs +0 -197
  237. package/templates/base/src/libs/popover/helpers/popover-dom.helper.ts.hbs +0 -75
  238. package/templates/base/src/libs/popover/popover.ts.hbs +0 -138
  239. package/templates/base/src/libs/snackbar/snackbar.ts.hbs +0 -75
  240. package/templates/base/src/styles/base/_functions.scss.hbs +0 -9
  241. package/templates/base/src/styles/core/_anchors.scss.hbs +0 -10
  242. package/templates/base/src/styles/core/_index.scss.hbs +0 -6
  243. package/templates/base/src/styles/core/_popover.scss.hbs +0 -96
  244. package/templates/base/src/styles/core/_snackbar.scss.hbs +0 -50
  245. package/templates/base/tools/builder/core/esbuild.js.hbs +0 -25
  246. package/templates/base/tools/builder/core/minify-html.js.hbs +0 -60
  247. package/templates/base/tools/builder/core/sass.js.hbs +0 -22
  248. package/templates/base/tools/builder/core/tsc.js.hbs +0 -12
  249. package/templates/base/tools/generator/templates/service.template.js.hbs +0 -17
  250. package/templates/base/tools/utils/export-flags.js.hbs +0 -6
  251. package/templates/features/deployHelper/tools/builder/core/compress-files.js.hbs +0 -56
  252. package/templates/features/deployHelper/tools/deployment/Dockerfile.hbs +0 -30
  253. package/templates/features/i18n/src/app/views/home/locales/en.json.hbs +0 -9
  254. package/templates/features/i18n/src/app/views/not-found/locales/en.json +0 -8
  255. package/templates/features/i18n/src/app/views/not-found/locales/fr.json +0 -8
  256. package/templates/features/i18n/src/core/config.ts.hbs +0 -3
  257. package/templates/features/i18n/src/core/services/i18n/i18n.test.js.hbs +0 -125
  258. package/templates/features/i18n/tools/generator/templates/json.template.js.hbs +0 -8
  259. package/templates/features/i18n/tools/utils/languages.js.hbs +0 -7
  260. package/templates/features/stylinNutin/src/styles/_custom-classes.scss.hbs +0 -9
  261. package/templates/features/stylinNutin/src/styles/base/_mixins.scss.hbs +0 -372
  262. package/templates/features/stylinNutin/src/styles/components/_index.scss.hbs +0 -3
  263. package/templates/features/stylinNutin/src/styles/core/_utilities.scss.hbs +0 -254
  264. package/templates/features/stylinNutin/src/styles/views/_index.scss.hbs +0 -0
  265. package/templates/features/stylinNutin/tools/generator/templates/scss.template.js.hbs +0 -4
  266. package/templates/features/template/src/app/views/home/home.view.html.hbs +0 -56
  267. package/templates/features/template/src/app/views/not-found/not-found.view.html.hbs +0 -19
  268. package/templates/features/template/tools/builder/core/merge-templates.js.hbs +0 -49
  269. package/templates/features/template/tools/generator/templates/html.template.js.hbs +0 -2
  270. package/templates/features/testinNutin/testin-nutin/core/index.js.hbs +0 -5
  271. package/templates/features/testinNutin/testin-nutin/core/src/utils/print.js.hbs +0 -64
  272. package/templates/features/testinNutin/testin-nutin/core/src/utils/test-queue.js.hbs +0 -64
  273. package/templates/features/testinNutin/testin-nutin/core/tests/globals-each-all.test.js.hbs +0 -28
  274. package/templates/features/testinNutin/testin-nutin/mocks/mock-store.js.hbs +0 -38
  275. package/templates/features/testinNutin/testin-nutin/runner.js.hbs +0 -36
  276. package/templates/features/testinNutin/testin-nutin/watch-tests.js.hbs +0 -21
  277. package/templates/features/testinNutin/testin-nutin.config.js.hbs +0 -14
  278. /package/lib/src/{template-compiler.mjs → common/template-compiler.mjs} +0 -0
  279. /package/templates/{features/i18n → base}/src/core/base-classes/base-component/helpers/i18n.helper.ts.hbs +0 -0
  280. /package/templates/{features/i18n → base}/src/core/services/i18n/languages.ts.hbs +0 -0
  281. /package/templates/base/tools/builder/{variables → core/app}/binary-extensions.js.hbs +0 -0
  282. /package/templates/base/tools/builder/core/{paths.js.hbs → app/paths.js.hbs} +0 -0
  283. /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/queue.js.hbs +0 -0
  284. /package/templates/{features/testinNutin/testin-nutin/core/src/utils → base/tools/testin-nutin/core/queue}/test-discovery.js.hbs +0 -0
  285. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-http-client.js.hbs +0 -0
  286. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-i18n.js.hbs +0 -0
  287. /package/templates/{features/testinNutin → base/tools}/testin-nutin/mocks/mock-router.js.hbs +0 -0
package/lib/src/print.mjs DELETED
@@ -1,32 +0,0 @@
1
- export const chalk = {
2
- green: (s) => `\x1b[32m${s}\x1b[0m`,
3
- red: (s) => `\x1b[31m${s}\x1b[0m`,
4
- blue: (s) => `\x1b[34m${s}\x1b[0m`,
5
- yellow: (s) => `\x1b[33m${s}\x1b[0m`,
6
- cyan: (s) => `\x1b[36m${s}\x1b[0m`,
7
- purple: (s) => `\x1b[35m${s}\x1b[0m`,
8
- gray: (s) => `\x1b[90m${s}\x1b[0m`,
9
- boldGreen: (s) => `\x1b[1;32m${s}\x1b[0m`,
10
- boldRed: (s) => `\x1b[1;31m${s}\x1b[0m`,
11
- boldBlue: (s) => `\x1b[1;34m${s}\x1b[0m`,
12
- boldYellow: (s) => `\x1b[1;33m${s}\x1b[0m`,
13
- boldCyan: (s) => `\x1b[1;36m${s}\x1b[0m`,
14
- boldPurple: (s) => `\x1b[1;35m${s}\x1b[0m`,
15
- boldGray: (s) => `\x1b[1;90m${s}\x1b[0m`,
16
- };
17
-
18
- export const print = {
19
- head: (s) => console.log(`${chalk.purple(s)}`),
20
- boldHead : (s) => console.log(`${chalk.boldPurple(s)}`),
21
- section: (s) => console.log(`${chalk.yellow(s)}`),
22
- boldSection: (s) => console.log(`${chalk.boldYellow(s)}`),
23
- info: (s) => console.log(`${chalk.green(s)}`),
24
- boldInfo: (s) => console.log(`${chalk.boldGreen(s)}`),
25
- success: (s) => console.log(`${chalk.cyan(s)}`),
26
- boldSuccess: (s) => console.log(`${chalk.boldCyan(s)}`),
27
- error: (s) => console.error(`${chalk.red(s)}`),
28
- boldError: (s) => console.error(`${chalk.boldRed(s)}`),
29
- grayError: (s) => console.error(`${chalk.gray(s)}`),
30
- blue: (s) => console.log(`${chalk.blue(s)}`),
31
- boldBlue: (s) => console.log(`${chalk.boldBlue(s)}`),
32
- }
package/lib/src/utils.mjs DELETED
@@ -1,18 +0,0 @@
1
- import { exec } from 'child_process';
2
- import { promisify } from 'util';
3
- import { print } from './print.mjs';
4
-
5
- export const promiseExec = promisify(exec);
6
-
7
- export function displaySuccessMessage(answers) {
8
- const { projectName, packageManager, deployHelper } = answers;
9
- print.boldSuccess('\n🎉 Your project is ready!');
10
- print.boldInfo(`Documentation on https://www.nutin.org`);
11
-
12
- if (packageManager === 'pnpm' || packageManager === 'bun') {
13
- if (deployHelper) print.boldError(`You'll need to modify the Dockerfile to support ${packageManager}`)
14
- }
15
-
16
- print.info('Next steps:');
17
- print.info(` cd ${projectName} && ${packageManager} run serve\n`);
18
- }
@@ -1 +0,0 @@
1
- export const packageVersion = '1.3.1';
@@ -1,36 +0,0 @@
1
- export default {
2
- esbuild: {
3
- bundle: true,
4
- minify: true,
5
- sourcemap: false,
6
- drop: ['console', 'debugger'],
7
- platform: 'browser',
8
- format: 'esm',
9
- target: ['es2015'],
10
- legalComments: 'none',
11
- loader: {
12
- '.json': 'json',
13
- },
14
- define: {
15
- 'process.env.NODE_ENV': '"production"',
16
- },
17
- },
18
- sass: {
19
- paths: [
20
- 'base',
21
- 'core',
22
- {{#if stylinNutin}}
23
- 'components',
24
- 'views',
25
- {{/if}}
26
- ], // in styles/
27
- },
28
- {{#if deployHelper}}
29
- compression: {
30
- gzip: true,
31
- // BROTLI OPTIONAL
32
- // brotli: false,
33
- },
34
- {{/if}}
35
- verbose: false,
36
- }
@@ -1,32 +0,0 @@
1
- import { AnchorManager, Component, IAnchorConfig } from '../../../../core/index.js';
2
-
3
- /**
4
- * ```typescript
5
- * interface IAnchorConfig {
6
- // prefix href with '#' for internal anchor
7
- href: string;
8
- target?: string;
9
- textContent?: string;
10
- {{#if i18n}}
11
- i18nKey?: string;
12
- {{/if}}
13
- className?: string;
14
- style?: string;
15
- // use regular pipe syntax for arguments / chaining
16
- pipes?: string;
17
- tagName?: keyof HTMLElementTagNameMap;
18
- }
19
- ```
20
- */
21
- export class AnchorComponent extends Component<HTMLAnchorElement, IAnchorConfig> {
22
-
23
- constructor(mountTarget: HTMLElement, config: IAnchorConfig) {
24
- super({
25
- mountTarget,
26
- tagName: config.tagName,
27
- config,
28
- normalizeKeys: ['style', 'pipes', 'className']
29
- });
30
- new AnchorManager(config, this.element);
31
- }
32
- }
@@ -1,40 +0,0 @@
1
- import { BaseButton, Component } from '../../../../core/index.js';
2
-
3
- /**
4
- * ```typescript
5
- interface IAttributesConfig {
6
- {{#if i18n}}
7
- i18nKey?: string;
8
- {{/if}}
9
- textContent?: string;
10
- className?: string;
11
- style?: string;
12
- // use regular pipe syntax for arguments / chaining
13
- pipes?: string;
14
- }
15
-
16
- interface BaseButton extends IAttributesConfig {
17
- callback: () => void;
18
- }
19
-
20
- interface ButtonContainerOptions {
21
- containerClassName?: string;
22
- containerStyles?: string;
23
- }
24
- ```
25
- * Note : To ensure 'this' is bound properly
26
- * ```typescript
27
- // Will handle 'this' inside doStuff
28
- * { callback: () => this.doStuff() }
29
- * // Will still work, but won't handle 'this' inside doStuff
30
- * { callback: this.doStuff }
31
- * ```
32
- */
33
- export class ButtonComponent extends Component<HTMLButtonElement> {
34
- constructor(mountTarget: HTMLElement, button: BaseButton) {
35
- super({
36
- mountTarget,
37
- props: { buttons: [button] }
38
- });
39
- }
40
- }
@@ -1,13 +0,0 @@
1
- describe('App container', () => {
2
- it('should be defined', () => {
3
- const appContainer = document.getElementById('app');
4
- expect(appContainer).toBeDefined();
5
- });
6
- it('should have title', () => {
7
- expect(document.title).toEqual('{{projectName}}');
8
- });
9
- it('should have meta description', () => {
10
- const desc = document.querySelector('meta[name="description"]').content;
11
- expect(desc).toEqual('{{projectName}}');
12
- });
13
- });
@@ -1,18 +0,0 @@
1
- import { Service } from "../../../core/index.js";
2
-
3
- export class Example extends Service<Example> {
4
- constructor() {
5
- super();
6
- this.registerCallback();
7
- }
8
-
9
- protected registerCallback(): void {
10
- console.debug('No cleanup callbacks registered for service: Example')
11
- }
12
-
13
- protected onDestroy(): void {
14
- this.dispose();
15
- }
16
- }
17
-
18
- export const exampleService = Example.getInstance();
@@ -1,26 +0,0 @@
1
- import { HomeView } from '#root/dist/src/app/views/index.js';
2
-
3
- let view;
4
-
5
- describe('HomeView', () => {
6
- beforeAll(() => {
7
- view = new HomeView();
8
- });
9
-
10
- it('should be defined', () => {
11
- expect(view).toBeDefined();
12
- });
13
- {{#if i18n}}
14
- it('should have title with i18n key', () => {
15
- const h1 = view.element.querySelector('h1');
16
- expect(h1).toBeDefined();
17
- expect(h1.textContent).toBe('home.title');
18
- });
19
- {{else}}
20
- it('should have title', () => {
21
- const h1 = view.element.querySelector('h1');
22
- expect(h1).toBeDefined();
23
- expect(h1.textContent).toBe('{{projectName}}');
24
- });
25
- {{/if}}
26
- })
@@ -1,8 +0,0 @@
1
- import { AppStore } from '#root/dist/src/core/services/index.js'
2
-
3
- describe('store', () => {
4
- it('should set & get values properly', () => {
5
- AppStore.set('foo', 123);
6
- expect(AppStore.get('foo')).toBe(123)
7
- });
8
- })
@@ -1,39 +0,0 @@
1
- import { Service, AppEventBus } from "../../index.js";
2
-
3
- export type StoreState = Record<string, any>;
4
-
5
- export class Store extends Service<Store> {
6
- private _state: StoreState = {};
7
-
8
- constructor() {
9
- super();
10
- this.registerCleanup(this.clear);
11
- }
12
-
13
- public set<T = any>(key: string, value: T): void {
14
- this._state[key] = value;
15
- AppEventBus.emit(`store:${key}`, value);
16
- }
17
-
18
- public get<T = any>(key: string): T | undefined {
19
- return this._state[key];
20
- }
21
-
22
- public subscribe<T = any>(key: string, callback: (value: T) => void): void {
23
- AppEventBus.subscribe(`store:${key}`, callback);
24
- }
25
-
26
- public unsubscribe<T = any>(key: string, callback: (value: T) => void): void {
27
- AppEventBus.off(`store:${key}`, callback);
28
- }
29
-
30
- public clear(): void {
31
- this._state = {};
32
- }
33
-
34
- protected onDestroy(): void {
35
- this.clear();
36
- }
37
- }
38
-
39
- export const AppStore = Store.getInstance();
@@ -1,113 +0,0 @@
1
- import { AttributesHelper, IAttributesConfig } from "../helpers/attributes.helper.js";
2
-
3
- /**
4
- * ```typescript
5
- interface IAttributesConfig {
6
- {{#if i18n}}
7
- i18nKey?: string;
8
- {{/if}}
9
- textContent?: string;
10
- className?: string;
11
- style?: string;
12
- // use regular pipe syntax for arguments / chaining
13
- pipes?: string;
14
- }
15
- interface IAnchorConfig extends IAttributesConfig {
16
- // prefix href with '#' for internal anchor
17
- href: string;
18
- target?: string;
19
- tagName?: keyof HTMLElementTagNameMap;
20
- }
21
- ```
22
- */
23
- export interface IAnchorConfig extends IAttributesConfig {
24
- href: string;
25
- target?: string;
26
- tagName?: keyof HTMLElementTagNameMap;
27
- }
28
-
29
- export class AnchorManager {
30
- private config: IAnchorConfig;
31
-
32
- constructor(
33
- config: IAnchorConfig,
34
- target: HTMLElement
35
- ) {
36
- this.config = config;
37
- this.appendAnchorElement(target);
38
- }
39
-
40
- private appendAnchorElement(target: HTMLElement): void {
41
- const container = this.createAnchorContainer();
42
- target.appendChild(container);
43
- }
44
-
45
- private createAnchorContainer(): HTMLSpanElement {
46
- const container = document.createElement('span');
47
- const anchor = this.createAnchor();
48
- container.appendChild(anchor);
49
- return container;
50
- }
51
-
52
- private createAnchor(): HTMLElement {
53
- const anchor = document.createElement('a');
54
- this.setAnchorRef(anchor);
55
- AttributesHelper.setAttributes(anchor, this.config);
56
- this.handleClick(anchor);
57
- return anchor;
58
- }
59
-
60
- private setAnchorRef(anchor: HTMLAnchorElement): void {
61
- anchor.setAttribute('href', this.config.href);
62
- if (this.config.target) {
63
- anchor.setAttribute('target', this.config.target);
64
- }
65
- }
66
-
67
- private handleClick(anchor: HTMLAnchorElement): void {
68
- const isInternal = this.config.href.startsWith('#');
69
- if (!isInternal) return;
70
-
71
- const id = this.config.href.slice(1);
72
-
73
- anchor?.addEventListener('click', (e) => {
74
- e.preventDefault();
75
- const target = document.getElementById(id);
76
- this.scrollToTarget(target);
77
- this.accessibilityFeatures(target, id);
78
- });
79
- }
80
-
81
- private scrollToTarget(target: HTMLElement | null): void {
82
- const targetPosition = target?.offsetTop;
83
- window.scrollTo({
84
- top: targetPosition,
85
- behavior: 'smooth'
86
- })
87
- }
88
-
89
- private accessibilityFeatures(target: HTMLElement | null, id: string) {
90
- this.setFocus(target);
91
- this.setAriaLive(target, id);
92
- }
93
-
94
- private setFocus(target: HTMLElement | null): void {
95
- setTimeout(() => {
96
- target?.setAttribute('tabindex', '-1');
97
- target?.focus({ preventScroll: true });
98
- // Remove tabindex after focus
99
- target?.addEventListener('blur', () => {
100
- target?.removeAttribute('tabindex');
101
- }, { once: true });
102
- }, 100);
103
- }
104
-
105
- private setAriaLive(target: HTMLElement | null, id: string): void {
106
- const announcement = document.createElement('div');
107
- announcement.setAttribute('aria-live', 'polite');
108
- announcement.className = 'sr-only';
109
- announcement.textContent = `Navigated to ${ target?.textContent || id }`;
110
- document.body.appendChild(announcement);
111
- setTimeout(() => document.body.removeChild(announcement), 1000);
112
- }
113
- }
@@ -1,249 +0,0 @@
1
- import { ButtonManager } from '#root/dist/src/core/index.js';
2
-
3
- describe('ButtonManager', () => {
4
- it('should initialize with default options', () => {
5
- const mockComponent = {};
6
- const manager = new ButtonManager(mockComponent);
7
-
8
- expect(manager.component).toBe(mockComponent);
9
- expect(manager.buttons.length).toBe(0);
10
- expect(manager.containerOptions.containerClassName).toBe('dynamic-buttons');
11
- });
12
-
13
- it('should initialize with custom options', () => {
14
- const mockComponent = {};
15
- const buttons = [{ {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'test' }];
16
- const options = {
17
- containerClassName: 'custom-container',
18
- buttonClassName: 'custom-button'
19
- };
20
-
21
- const manager = new ButtonManager(mockComponent, buttons, options);
22
-
23
- expect(manager.buttons.length).toBe(1);
24
- expect(manager.containerOptions.containerClassName).toBe('custom-container');
25
- expect(manager.containerOptions.buttonClassName).toBe('custom-button');
26
- });
27
-
28
- it('should return null for empty buttons array', () => {
29
- const mockComponent = {};
30
- const manager = new ButtonManager(mockComponent, []);
31
-
32
- const container = manager.createButtonContainer();
33
- expect(container).toBeUndefined();
34
- });
35
-
36
- it('should return null for undefined buttons', () => {
37
- const mockComponent = {};
38
- const manager = new ButtonManager(mockComponent);
39
-
40
- const container = manager.createButtonContainer();
41
- expect(container).toBeUndefined();
42
- });
43
-
44
- it('should create container with correct class name', () => {
45
- const mockComponent = {};
46
- const buttons = [{ {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'test' }];
47
- const manager = new ButtonManager(mockComponent, buttons);
48
-
49
- const container = manager.createButtonContainer();
50
-
51
- expect(container).toBeDefined();
52
- expect(container.className).toBe('dynamic-buttons');
53
- });
54
-
55
- it('should create container with custom class name', () => {
56
- const mockComponent = {};
57
- const buttons = [{ {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'test' }];
58
- const options = { containerClassName: 'my-buttons' };
59
- const manager = new ButtonManager(mockComponent, buttons, options);
60
-
61
- const container = manager.createButtonContainer();
62
-
63
- expect(container.className).toBe('my-buttons');
64
- });
65
-
66
- it('should create correct number of buttons', () => {
67
- const mockComponent = {};
68
- const buttons = [
69
- { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'button1' },
70
- { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'button2' },
71
- { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'button3' }
72
- ];
73
- const manager = new ButtonManager(mockComponent, buttons);
74
-
75
- const container = manager.createButtonContainer();
76
-
77
- expect(container.children.length).toBe(3);
78
- });
79
-
80
- it('should create button with {{#if i18n}}i18nKey{{else}}textContent{{/if}} as text', () => {
81
- const mockComponent = {};
82
- const manager = new ButtonManager(mockComponent);
83
- const btn = { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'save' };
84
-
85
- const button = manager.createButton(btn, 0);
86
-
87
- {{#if i18n}}
88
- expect(button.getAttribute('data-i18n')).toBe('save');
89
- {{else}}
90
- expect(button.textContent).toBe('save');
91
- {{/if}}
92
- });
93
- {{#if i18n}}
94
-
95
- it('should prioritize textContent over i18nKey', () => {
96
- const mockComponent = {};
97
- const manager = new ButtonManager(mockComponent);
98
- const btn = {
99
- i18nKey: 'save',
100
- textContent: 'Save Document'
101
- };
102
-
103
- const button = manager.createButton(btn, 0);
104
-
105
- expect(button.textContent).toBe('Save Document');
106
- expect(button.getAttribute('data-i18n')).toBe('save');
107
- });
108
- {{/if}}
109
-
110
- it('should set button className correctly', () => {
111
- const mockComponent = {};
112
- const manager = new ButtonManager(mockComponent, []);
113
- const btn = {
114
- i18nKey: 'save',
115
- className: 'btn-primary'
116
- };
117
-
118
- const button = manager.createButton(btn, 0);
119
-
120
- expect(button.className).toBe('btn-primary');
121
- });
122
-
123
- it('should set data-event attribute correctly', () => {
124
- const mockComponent = {};
125
- const manager = new ButtonManager(mockComponent);
126
- const btn = { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'save' };
127
-
128
- const button = manager.createButton(btn, 2);
129
-
130
- expect(button.getAttribute('data-event')).toBe('click:onButtonClick_2');
131
- });
132
-
133
- it('should bind callback method to component', () => {
134
- const mockComponent = {};
135
- const manager = new ButtonManager(mockComponent);
136
- const btn = {
137
- {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'test',
138
- callback: () => 'called'
139
- };
140
-
141
- manager.bindButtonCallback(btn, 1);
142
-
143
- expect(typeof mockComponent.onButtonClick_1).toBe('function')
144
- });
145
-
146
- it('should execute callback when bound method is called', () => {
147
- const mockComponent = {};
148
- const manager = new ButtonManager(mockComponent);
149
- let callbackExecuted = false;
150
- const btn = {
151
- {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'test',
152
- callback: () => { callbackExecuted = true; }
153
- };
154
-
155
- manager.bindButtonCallback(btn, 0);
156
- mockComponent.onButtonClick_0();
157
-
158
- expect(callbackExecuted).toBe(true);
159
- });
160
-
161
- it('should append button container to target element', () => {
162
- const mockComponent = {};
163
- const buttons = [{ {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'test' }];
164
- const manager = new ButtonManager(mockComponent, buttons);
165
- const target = document.createElement('div');
166
-
167
- manager.appendTo(target);
168
-
169
- expect(target.children.length).toBe(1);
170
- expect(target.children[0].className).toBe('dynamic-buttons')
171
- });
172
-
173
- it('should not append anything for empty buttons', () => {
174
- const mockComponent = {};
175
- const manager = new ButtonManager(mockComponent, []);
176
- const target = document.createElement('div');
177
-
178
- manager.appendTo(target);
179
-
180
- expect(target.children.length).toBe(0);
181
- });
182
-
183
- it('should create complete button setup end-to-end', () => {
184
- const mockComponent = {};
185
- let button1Clicked = false;
186
- let button2Clicked = false;
187
-
188
- const buttons = [
189
- {
190
- {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'save',
191
- className: 'btn-primary',
192
- callback: () => { button1Clicked = true; }
193
- },
194
- {
195
- {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'cancel',
196
- textContent: 'Cancel Action',
197
- className: 'btn-secondary',
198
- callback: () => { button2Clicked = true; }
199
- }
200
- ];
201
-
202
- const manager = new ButtonManager(mockComponent, buttons, {
203
- containerClassName: 'form-buttons'
204
- });
205
-
206
- const container = manager.createButtonContainer();
207
-
208
- expect(container.className).toBe('form-buttons');
209
- expect(container.children.length).toBe(2);
210
-
211
- const firstButton = container.children[0];
212
- expect(firstButton.className).toBe('btn-primary');
213
- expect(firstButton.getAttribute('data-event')).toBe('click:onButtonClick_0');
214
-
215
- const secondButton = container.children[1];
216
- expect(secondButton.className).toBe('btn-secondary');
217
- expect(secondButton.getAttribute('data-event')).toBe('click:onButtonClick_1');
218
-
219
- mockComponent.onButtonClick_0();
220
- mockComponent.onButtonClick_1();
221
-
222
- expect(button1Clicked).toBe(true);
223
- expect(button2Clicked).toBe(true);
224
- });
225
-
226
- it('should handle button with empty {{#if i18n}}i18nKey{{else}}textContent{{/if}}', () => {
227
- const mockComponent = {};
228
- const manager = new ButtonManager(mockComponent);
229
- const btn = { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: '' };
230
-
231
- const button = manager.createButton(btn, 0);
232
-
233
- expect(button.textContent).toBe('');
234
- expect(button.getAttribute('data-i18n')).toBe(null);
235
- });
236
-
237
- it('should handle updateButtons method', () => {
238
- const mockComponent = {};
239
- const initialButtons = [{ {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'initial' }];
240
- const manager = new ButtonManager(mockComponent, initialButtons);
241
-
242
- const newButtons = [{ {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'new1' }, { {{#if i18n}}i18nKey{{else}}textContent{{/if}}: 'new2' }];
243
- manager.updateButtons(newButtons);
244
-
245
- expect(manager.buttons.length).toBe(2);
246
- expect(manager.buttons[0].{{#if i18n}}i18nKey{{else}}textContent{{/if}}).toBe('new1');
247
- expect(manager.buttons[1].{{#if i18n}}i18nKey{{else}}textContent{{/if}}).toBe('new2');
248
- });
249
- })