@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
@@ -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
- })
@@ -1,131 +0,0 @@
1
- import { AttributesHelper, IAttributesConfig } from "../helpers/attributes.helper.js";
2
-
3
- export interface BaseButton extends IAttributesConfig {
4
- callback: () => void;
5
- label?: string;
6
- }
7
-
8
- export interface ButtonContainerOptions {
9
- containerClassName?: string;
10
- containerStyles?: string;
11
- }
12
-
13
- /**
14
- * ```typescript
15
- interface IAttributesConfig {
16
- {{#if i18n}}
17
- i18nKey?: string;
18
- {{/if}}
19
- textContent?: string;
20
- className?: string;
21
- style?: string;
22
- // use regular pipe syntax for arguments / chaining
23
- pipes?: string;
24
- }
25
-
26
- interface ButtonContainerOptions {
27
- containerClassName?: string;
28
- containerStyles?: string;
29
- }
30
- ```
31
- */
32
- export class ButtonManager {
33
- private component: any;
34
- private buttons: BaseButton[];
35
- private containerOptions: ButtonContainerOptions;
36
-
37
- constructor(
38
- component: any,
39
- buttons: BaseButton[] = [],
40
- containerOptions: ButtonContainerOptions = {}
41
- ) {
42
- this.component = component;
43
- this.buttons = buttons;
44
- this.containerOptions = {
45
- containerClassName: 'dynamic-buttons',
46
- containerStyles: '',
47
- ...containerOptions
48
- };
49
- }
50
-
51
- public createButtonContainer(): HTMLElement | null {
52
- if (!Array.isArray(this.buttons) || this.buttons.length === 0) {
53
- return null;
54
- }
55
-
56
- const container = document.createElement('div');
57
- container.className = this.containerOptions.containerClassName || 'dynamic-buttons';
58
- container.style = this.containerOptions.containerStyles || '';
59
-
60
- this.buttons.forEach((config, index) => {
61
- if (config.label) {
62
- return this.createButtonWithCheckbox(config, index, container);
63
- } else {
64
- const button = this.createButton(config, index);
65
- container.appendChild(button);
66
- this.bindButtonCallback(config, index);
67
- }
68
- });
69
-
70
- return container;
71
- }
72
-
73
- public appendTo(target: HTMLElement): void {
74
- const container = this.createButtonContainer();
75
- if (container) {
76
- target.appendChild(container);
77
- }
78
- }
79
-
80
- private createButtonWithCheckbox(config: BaseButton, index: number, container: HTMLElement): HTMLElement {
81
- if (!config.label) return container;
82
- const checkbox = document.createElement('input');
83
- checkbox.setAttribute('type', 'checkbox');
84
- checkbox.setAttribute('id', config.label);
85
- checkbox.hidden = true;
86
- container.appendChild(checkbox);
87
-
88
- const label = document.createElement('label');
89
- label.setAttribute('for', config.label);
90
-
91
- const button = this.createButton(config, index);
92
- label.appendChild(button);
93
-
94
- container.appendChild(label);
95
- this.bindButtonCallback(config, index, checkbox);
96
- return container;
97
- }
98
-
99
- private createButton(config: BaseButton, index: number): HTMLElement {
100
- const button = document.createElement('button');
101
-
102
- AttributesHelper.setAttributes(button, config);
103
-
104
- this.setDataEvent(button, index);
105
-
106
- return button;
107
- }
108
-
109
- private setDataEvent(button: HTMLButtonElement, index: number): void {
110
- button.setAttribute('data-event', `click:onButtonClick_${index}`);
111
- }
112
-
113
- private bindButtonCallback(config: BaseButton, index: number, checkbox?: HTMLInputElement): void {
114
- const methodName = `onButtonClick_${index}`;
115
-
116
- this.component[methodName] = () => {
117
- if (typeof config.callback === 'function') {
118
- config.callback();
119
- if (checkbox) {
120
- checkbox.checked = !checkbox.checked;
121
- }
122
- }
123
- };
124
- }
125
-
126
- /** Note : doesn't track container
127
- */
128
- public updateButtons(newButtons: BaseButton[]): void {
129
- this.buttons = newButtons;
130
- }
131
- }
@@ -1,50 +0,0 @@
1
- export interface IAttributesConfig {
2
- {{#if i18n}}
3
- i18nKey?: string;
4
- {{/if}}
5
- textContent?: string;
6
- className?: string;
7
- style?: string;
8
- // use regular pipe syntax for arguments / chaining
9
- pipes?: string;
10
- }
11
-
12
- export class AttributesHelper {
13
- public static setAttributes(element: HTMLElement, config: IAttributesConfig): void {
14
- this.setContent(element, config);
15
- this.setPipes(element, config);
16
- this.setStyle(element, config);
17
- }
18
-
19
- private static setContent(element: HTMLElement, config: IAttributesConfig): void {
20
- element.textContent = config.textContent || '';
21
- {{#if i18n}}
22
- if (config.i18nKey) {
23
- element.setAttribute('data-i18n', config.i18nKey);
24
- }
25
- {{/if}}
26
- }
27
-
28
- private static setPipes(element: HTMLElement, config: IAttributesConfig): void {
29
- if (!config.pipes) return;
30
- element.setAttribute('data-pipe', config.pipes);
31
- }
32
-
33
- private static setStyle(element: HTMLElement, config: IAttributesConfig): void {
34
- const classes = [
35
- config.className
36
- ].filter(Boolean).join(' ');
37
-
38
- const style = [
39
- config.style
40
- ].filter(Boolean).join(' ');
41
-
42
- if (classes) {
43
- element.className = classes;
44
- }
45
-
46
- if(style) {
47
- element.style = style;
48
- }
49
- }
50
- }
@@ -1,2 +0,0 @@
1
- export * from './button-manager/button-manager.utils.js';
2
- export * from './anchor-manager/anchor-manager.utils.js';
@@ -1,4 +0,0 @@
1
- export * from './snackbar/snackbar.js';
2
- export * from './popover/popover.js';
3
- export * from './guards/guards.js';
4
- export * from './pipes/pipes.js';
@@ -1,197 +0,0 @@
1
- import { AppEventBus } from "../../../core/index.js";
2
-
3
- type KeyboardEventHandler = (event: KeyboardEvent) => void;
4
-
5
- export interface IFocusTrapOptions {
6
- escapeDeactivates?: boolean;
7
- clickOutsideDeactivates?: boolean;
8
- returnFocusOnDeactivate?: boolean;
9
- }
10
-
11
- export interface IFocusTrapHelperParams {
12
- container: HTMLElement;
13
- overlay: HTMLElement;
14
- options?: IFocusTrapOptions;
15
- }
16
-
17
- export class FocusTrapHelper {
18
- private _container: HTMLElement;
19
- private _overlay: HTMLElement;
20
- private _previousActiveElement: HTMLElement | null | undefined = null;
21
- private _focusableElements: NodeListOf<HTMLElement> | null | undefined = null;
22
- private _firstFocusableElement: HTMLElement | null | undefined = null;
23
- private _lastFocusableElement: HTMLElement | null | undefined = null;
24
- private _boundKeyDown: KeyboardEventHandler;
25
- private _options: IFocusTrapOptions;
26
- private _isActive: boolean = false;
27
-
28
- constructor({container, overlay, options = {}}: IFocusTrapHelperParams) {
29
- this._container = container;
30
- this._overlay = overlay;
31
- this._options = {
32
- escapeDeactivates: true,
33
- clickOutsideDeactivates: true,
34
- returnFocusOnDeactivate: true,
35
- ...options
36
- };
37
- this._boundKeyDown = this._handleKeyDown.bind(this);
38
- }
39
-
40
- private _getFocusableElements(): NodeListOf<HTMLElement> {
41
- return this._container.querySelectorAll(
42
- 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'
43
- ) as NodeListOf<HTMLElement>;
44
- }
45
-
46
- public activate(): void {
47
- if (this._isActive) return;
48
-
49
- this._previousActiveElement = document.activeElement as HTMLElement;
50
-
51
- this._focusableElements = this._getFocusableElements();
52
-
53
- if (this._focusableElements.length > 0) {
54
- this._firstFocusableElement = this._focusableElements[0];
55
- this._lastFocusableElement = this._focusableElements[this._focusableElements.length - 1];
56
-
57
- this._firstFocusableElement?.focus();
58
- } else {
59
- this._container.setAttribute('tabindex', '-1');
60
- this._container.focus();
61
- this._firstFocusableElement = this._container;
62
- this._lastFocusableElement = this._container;
63
- }
64
-
65
- this._container.addEventListener('keydown', this._boundKeyDown);
66
-
67
- document.addEventListener('click', this._handleOutsideClick.bind(this));
68
-
69
- this._disableOutsideTabIndex();
70
-
71
- this._isActive = true;
72
- }
73
-
74
- public deactivate(): void {
75
- if (!this._isActive) return;
76
-
77
- this._container.removeEventListener('keydown', this._boundKeyDown);
78
- document.removeEventListener('click', this._handleOutsideClick.bind(this));
79
-
80
- this._enableOutsideTabIndex();
81
-
82
- if (this._container.getAttribute('tabindex') === '-1') {
83
- this._container.removeAttribute('tabindex');
84
- }
85
-
86
- if (this._options.returnFocusOnDeactivate &&
87
- this._previousActiveElement &&
88
- this._previousActiveElement.focus
89
- ) {
90
- this._previousActiveElement.focus();
91
- }
92
-
93
- this._focusableElements = null;
94
- this._firstFocusableElement = null;
95
- this._lastFocusableElement = null;
96
- this._previousActiveElement = null;
97
-
98
- this._isActive = false;
99
- }
100
-
101
- public getIsActive(): boolean {
102
- return this._isActive;
103
- }
104
-
105
- public updateFocusableElements(): void {
106
- if (!this._isActive) return;
107
-
108
- this._focusableElements = this._getFocusableElements();
109
-
110
- if (this._focusableElements.length > 0) {
111
- this._firstFocusableElement = this._focusableElements[0];
112
- this._lastFocusableElement = this._focusableElements[this._focusableElements.length - 1];
113
- }
114
- }
115
-
116
- private _disableOutsideTabIndex(): void {
117
- const allElements = document.querySelectorAll('body *') as NodeListOf<HTMLElement>;
118
-
119
- allElements.forEach((el: HTMLElement) => {
120
- if (!this._container.contains(el)) {
121
- const currentTabIndex = el.getAttribute('tabindex');
122
- if (currentTabIndex !== '-1') {
123
- const originalTabIndex = currentTabIndex ||
124
- (el.tabIndex !== -1 ? el.tabIndex.toString() : null);
125
-
126
- if (originalTabIndex !== null) {
127
- el.setAttribute('data-original-tabindex', originalTabIndex);
128
- }
129
-
130
- el.setAttribute('tabindex', '-1');
131
- }
132
- }
133
- });
134
- }
135
-
136
- private _enableOutsideTabIndex(): void {
137
- const allElements = document.querySelectorAll(
138
- '[data-original-tabindex]'
139
- ) as NodeListOf<HTMLElement>;
140
-
141
- allElements.forEach((el: HTMLElement) => {
142
- const originalTabIndex = el.getAttribute('data-original-tabindex');
143
-
144
- if (originalTabIndex === null) {
145
- el.removeAttribute('tabindex');
146
- } else if (originalTabIndex === '0') {
147
- el.removeAttribute('tabindex');
148
- } else {
149
- el.setAttribute('tabindex', originalTabIndex);
150
- }
151
-
152
- el.removeAttribute('data-original-tabindex');
153
- });
154
- }
155
-
156
- private _handleKeyDown(event: KeyboardEvent): void {
157
- switch (event.key) {
158
- case 'Tab':
159
- this._handleTabKey(event);
160
- break;
161
- case 'Escape':
162
- if (this._options.escapeDeactivates) {
163
- event.preventDefault();
164
- AppEventBus.emit('popover-close');
165
- this.deactivate();
166
- }
167
- break;
168
- }
169
- }
170
-
171
- private _handleTabKey(event: KeyboardEvent): void {
172
- if (!this._focusableElements || this._focusableElements.length === 0) return;
173
-
174
- if (event.shiftKey) {
175
- if (document.activeElement === this._firstFocusableElement) {
176
- event.preventDefault();
177
- this._lastFocusableElement?.focus();
178
- }
179
- } else {
180
- if (document.activeElement === this._lastFocusableElement) {
181
- event.preventDefault();
182
- this._firstFocusableElement?.focus();
183
- }
184
- }
185
- }
186
-
187
- private _handleOutsideClick(event: MouseEvent): void {
188
- if (!this._options.clickOutsideDeactivates) return;
189
- this._overlay.addEventListener('click', (e: MouseEvent) => {
190
- if (e.target === this._overlay){
191
- event.stopPropagation();
192
- AppEventBus.emit('popover-close');
193
- this.deactivate();;
194
- }
195
- });
196
- }
197
- }