@nutin/cli 2.1.1 → 3.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 (229) hide show
  1. package/CHANGELOG.md +268 -0
  2. package/README.md +13 -5
  3. package/bin/add-feature.mjs +1 -1
  4. package/bin/cli.mjs +1 -1
  5. package/bin/create-app.mjs +1 -1
  6. package/bin/update-app.mjs +1 -1
  7. package/lib/index.mjs +6 -2
  8. package/lib/src/add-feature/base-template-patcher.mjs +139 -0
  9. package/lib/src/add-feature/feature-adder.mjs +20 -9
  10. package/lib/src/add-feature/feature-context-builder.mjs +1 -0
  11. package/lib/src/add-feature/nutin-config-updater.mjs +34 -8
  12. package/lib/src/add-feature/package-json-updater.mjs +7 -9
  13. package/lib/src/common/feature-registry.mjs +4 -0
  14. package/lib/src/common/file-generator.mjs +25 -3
  15. package/lib/src/common/git.mjs +31 -0
  16. package/lib/src/common/meta-bootstrap-prompt.mjs +28 -2
  17. package/lib/src/common/package-json-helper.mjs +14 -4
  18. package/lib/src/common/project-meta.mjs +2 -2
  19. package/lib/src/common/template-compiler.mjs +2 -0
  20. package/lib/src/common/transpile-ts.mjs +94 -0
  21. package/lib/src/create-app/context-builder.mjs +1 -0
  22. package/lib/src/create-app/git-manager.mjs +12 -2
  23. package/lib/src/create-app/json-manager.mjs +21 -18
  24. package/lib/src/create-app/new-app-prompt.mjs +4 -2
  25. package/lib/src/create-app/success-message.mjs +1 -1
  26. package/lib/src/update-app/conflict-report-writer.mjs +33 -21
  27. package/lib/src/update-app/json-drift.mjs +54 -0
  28. package/lib/src/update-app/project-updater.mjs +123 -14
  29. package/lib/src/update-app/template-differ.mjs +5 -5
  30. package/lib/src/update-app/three-way-merge.mjs +42 -0
  31. package/lib/src/update-app/update-context-builder.mjs +1 -0
  32. package/lib/src/update-app/update-summary-printer.mjs +10 -2
  33. package/package.json +9 -8
  34. package/templates/base/AGENTS.md.hbs +42 -41
  35. package/templates/base/GETTING_STARTED.md.hbs +26 -20
  36. package/templates/base/README.md.hbs +7 -4
  37. package/templates/base/src/app/globals.d.ts.hbs +6 -3
  38. package/templates/base/src/app/guards.ts.hbs +1 -3
  39. package/templates/base/src/app/main.ts.hbs +2 -9
  40. package/templates/base/src/app/routes.ts.hbs +7 -2
  41. package/templates/base/src/app/views/home/home.view.html.hbs +1 -1
  42. package/templates/base/src/app/views/home/home.view.ts.hbs +2 -2
  43. package/templates/base/src/app/views/not-found/not-found.view.ts.hbs +2 -2
  44. package/templates/base/src/core/base-classes/base-component/base-component.test.js.hbs +461 -1
  45. package/templates/base/src/core/base-classes/base-component/base-component.ts.hbs +39 -48
  46. package/templates/base/src/core/base-classes/base-component/helpers/catalog.helper.test.js.hbs +36 -1
  47. package/templates/base/src/core/base-classes/base-component/helpers/catalog.helper.ts.hbs +47 -77
  48. package/templates/base/src/core/base-classes/base-component/helpers/children.helper.test.js.hbs +286 -24
  49. package/templates/base/src/core/base-classes/base-component/helpers/children.helper.ts.hbs +144 -26
  50. package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.test.js.hbs +66 -4
  51. package/templates/base/src/core/base-classes/base-component/helpers/dom.helper.ts.hbs +135 -75
  52. package/templates/base/src/core/base-classes/base-component/helpers/event.helper.test.js.hbs +85 -4
  53. package/templates/base/src/core/base-classes/base-component/helpers/event.helper.ts.hbs +93 -54
  54. package/templates/base/src/core/base-classes/base-component/helpers/html.helper.test.js.hbs +404 -0
  55. package/templates/base/src/core/base-classes/base-component/helpers/html.helper.ts.hbs +242 -0
  56. package/templates/base/src/core/base-classes/base-component/helpers/i18n.helper.test.js.hbs +70 -1
  57. package/templates/base/src/core/base-classes/base-component/helpers/i18n.helper.ts.hbs +54 -15
  58. package/templates/base/src/core/base-classes/base-component/helpers/pipe.helper.test.js.hbs +12 -1
  59. package/templates/base/src/core/base-classes/base-component/helpers/pipe.helper.ts.hbs +39 -36
  60. package/templates/base/src/core/base-classes/base-component/helpers/preservation.helper.test.js.hbs +179 -0
  61. package/templates/base/src/core/base-classes/base-component/helpers/preservation.helper.ts.hbs +93 -0
  62. package/templates/base/src/core/base-classes/base-component/helpers/security.helper.test.js.hbs +135 -17
  63. package/templates/base/src/core/base-classes/base-component/helpers/security.helper.ts.hbs +199 -81
  64. package/templates/base/src/core/base-classes/base-component/helpers/token.helper.test.js.hbs +40 -23
  65. package/templates/base/src/core/base-classes/base-component/helpers/token.helper.ts.hbs +67 -65
  66. package/templates/base/src/core/base-classes/component/component.test.js.hbs +17 -17
  67. package/templates/base/src/core/base-classes/component/component.ts.hbs +8 -41
  68. package/templates/base/src/core/base-classes/component/helpers/config.helper.test.js.hbs +1 -1
  69. package/templates/base/src/core/base-classes/component/helpers/config.helper.ts.hbs +37 -39
  70. package/templates/base/src/core/base-classes/component/helpers/data-binding.helper.test.js.hbs +14 -1
  71. package/templates/base/src/core/base-classes/component/helpers/data-binding.helper.ts.hbs +33 -31
  72. package/templates/base/src/core/base-classes/service/service.test.js.hbs +32 -0
  73. package/templates/base/src/core/base-classes/service/service.ts.hbs +21 -13
  74. package/templates/base/src/core/base-classes/view/view.test.js.hbs +4 -0
  75. package/templates/base/src/core/base-classes/view/view.ts.hbs +11 -8
  76. package/templates/base/src/core/index.ts.hbs +4 -2
  77. package/templates/base/src/core/internals.d.ts.hbs +199 -20
  78. package/templates/base/src/core/services/event-bus/event-bus.test.js.hbs +18 -0
  79. package/templates/base/src/core/services/event-bus/event-bus.ts.hbs +26 -25
  80. package/templates/base/src/core/services/event-bus/lifecycle.facade.ts.hbs +3 -3
  81. package/templates/base/src/core/services/event-bus/navigation.facade.ts.hbs +3 -3
  82. package/templates/base/src/core/services/globals/globals.ts.hbs +7 -32
  83. package/templates/base/src/core/services/http-client/helpers/http-builder.helper.test.js.hbs +133 -50
  84. package/templates/base/src/core/services/http-client/helpers/http-builder.helper.ts.hbs +147 -39
  85. package/templates/base/src/core/services/http-client/helpers/http-manager.helper.test.js.hbs +75 -19
  86. package/templates/base/src/core/services/http-client/helpers/http-manager.helper.ts.hbs +73 -47
  87. package/templates/base/src/core/services/http-client/http-client.test.js.hbs +339 -232
  88. package/templates/base/src/core/services/http-client/http-client.ts.hbs +37 -25
  89. package/templates/base/src/core/services/i18n/i18n.test.js.hbs +57 -16
  90. package/templates/base/src/core/services/i18n/i18n.ts.hbs +42 -42
  91. package/templates/base/src/core/services/i18n/languages.ts.hbs +0 -2
  92. package/templates/base/src/core/services/pipe-registry/pipe-registry.ts.hbs +4 -6
  93. package/templates/base/src/core/services/pipe-registry/pipes.test.js.hbs +10 -0
  94. package/templates/base/src/core/services/pipe-registry/pipes.ts.hbs +4 -2
  95. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.test.js.hbs +183 -4
  96. package/templates/base/src/core/services/router/helpers/navigation-manager.helper.ts.hbs +207 -84
  97. package/templates/base/src/core/services/router/helpers/route-guard-manager.helper.test.js.hbs +26 -27
  98. package/templates/base/src/core/services/router/helpers/route-guard-manager.helper.ts.hbs +38 -60
  99. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.test.js.hbs +4 -4
  100. package/templates/base/src/core/services/router/helpers/view-render-manager.helper.ts.hbs +30 -30
  101. package/templates/base/src/core/services/router/router.test.js.hbs +306 -0
  102. package/templates/base/src/core/services/router/router.ts.hbs +113 -53
  103. package/templates/base/tools/builder/builder.config.js.hbs +6 -0
  104. package/templates/base/tools/builder/builder.js.hbs +18 -6
  105. package/templates/base/tools/builder/core/app/compile-ts.js.hbs +81 -6
  106. package/templates/base/tools/builder/core/app/copy-static.js.hbs +12 -1
  107. package/templates/base/tools/builder/core/app/handler-refs.js.hbs +114 -0
  108. package/templates/base/tools/builder/core/app/handler-refs.test.js.hbs +70 -0
  109. package/templates/base/tools/builder/core/app/paths.js.hbs +17 -0
  110. package/templates/base/tools/builder/core/app/route-keys.js.hbs +47 -0
  111. package/templates/base/tools/builder/core/app/route-keys.test.js.hbs +97 -0
  112. package/templates/base/tools/builder/core/app/ts-errors.js.hbs +58 -0
  113. package/templates/base/tools/builder/core/app/ts-errors.test.js.hbs +84 -0
  114. package/templates/base/tools/builder/core/app/validate-routes.js.hbs +21 -55
  115. package/templates/base/tools/builder/core/finalize-build.js.hbs +6 -0
  116. package/templates/base/tools/builder/core/html-index/validate-html.js.hbs +10 -2
  117. package/templates/base/tools/builder/core/html-templates/merge-templates.js.hbs +111 -23
  118. package/templates/base/tools/builder/core/html-templates/minify-templates.js.hbs +8 -0
  119. package/templates/base/tools/builder/core/html-templates/process-html-templates.js.hbs +5 -3
  120. package/templates/base/tools/builder/core/html-templates/template-literal.js.hbs +193 -0
  121. package/templates/base/tools/builder/core/html-templates/template-literal.test.js.hbs +69 -0
  122. package/templates/base/tools/builder/core/i18n/build-i18n.js.hbs +14 -6
  123. package/templates/base/tools/builder/core/prod-bundle/bundle-options.js.hbs +82 -0
  124. package/templates/base/tools/builder/core/prod-bundle/bundle-options.test.js.hbs +65 -0
  125. package/templates/base/tools/builder/core/prod-bundle/compress-files.js.hbs +6 -6
  126. package/templates/base/tools/builder/core/prod-bundle/esbuild.js.hbs +15 -7
  127. package/templates/base/tools/builder/core/prod-bundle/hash-files.js.hbs +4 -4
  128. package/templates/base/tools/builder/core/seo/generate-robots-txt.js.hbs +31 -13
  129. package/templates/base/tools/builder/core/seo/generate-robots-txt.test.js.hbs +48 -0
  130. package/templates/base/tools/builder/core/seo/generate-seo-files.js.hbs +3 -3
  131. package/templates/base/tools/builder/core/seo/generate-seo-html.js.hbs +43 -13
  132. package/templates/base/tools/builder/core/seo/generate-sitemap-xml.js.hbs +22 -7
  133. package/templates/base/tools/builder/core/seo/generate-sitemap-xml.test.js.hbs +30 -0
  134. package/templates/base/tools/builder/core/seo/html-substitutions.js.hbs +28 -21
  135. package/templates/base/tools/builder/core/seo/html-substitutions.test.js.hbs +45 -0
  136. package/templates/base/tools/builder/core/seo/route-output.js.hbs +24 -6
  137. package/templates/base/tools/builder/core/seo/route-output.test.js.hbs +31 -0
  138. package/templates/base/tools/builder/core/seo/seo-routes.js.hbs +29 -0
  139. package/templates/base/tools/builder/core/seo/seo-routes.test.js.hbs +21 -0
  140. package/templates/base/tools/builder/core/seo/ssr/ssr-bundle.js.hbs +6 -7
  141. package/templates/base/tools/builder/core/seo/ssr/ssr-polyfills.js.hbs +34 -5
  142. package/templates/base/tools/builder/core/seo/ssr/ssr-polyfills.test.js.hbs +48 -0
  143. package/templates/base/tools/builder/core/seo/ssr/ssr-render.js.hbs +24 -11
  144. package/templates/base/tools/builder/core/styles/sass.js.hbs +3 -2
  145. package/templates/base/tools/builder/core/styles/tailwind.js.hbs +19 -59
  146. package/templates/base/tools/dev/dev-serve.js.hbs +30 -5
  147. package/templates/base/tools/dev/serve.js.hbs +152 -22
  148. package/templates/base/tools/dev/watcher.js.hbs +34 -3
  149. package/templates/base/tools/generator/generator.js.hbs +1 -1
  150. package/templates/base/tools/generator/handle-file.js.hbs +4 -2
  151. package/templates/base/tools/generator/handle-file.test.js.hbs +3 -3
  152. package/templates/base/tools/generator/templates/component/component.template.js.hbs +3 -3
  153. package/templates/base/tools/generator/templates/component/component.template.test.js.hbs +3 -3
  154. package/templates/base/tools/generator/templates/service/service.template.js.hbs +1 -1
  155. package/templates/base/tools/generator/templates/service/service.template.test.js.hbs +1 -1
  156. package/templates/base/tools/generator/templates/view/view.template.js.hbs +2 -2
  157. package/templates/base/tools/generator/templates/view/view.template.test.js.hbs +2 -2
  158. package/templates/base/tools/testin-nutin/core/coverage/write-uncovered-report.js.hbs +1 -1
  159. package/templates/base/tools/testin-nutin/core/globals/assertion-lib.js.hbs +2 -2
  160. package/templates/base/tools/testin-nutin/core/{tests/assertions.test.js.hbs → globals/assertion-lib.test.js.hbs} +6 -0
  161. package/templates/base/tools/testin-nutin/core/globals/register-test-globals.js.hbs +6 -7
  162. package/templates/base/tools/testin-nutin/core/{tests/globals-each-all.test.js.hbs → globals/register-test-globals.test.js.hbs} +12 -0
  163. package/templates/base/tools/testin-nutin/core/printer.js.hbs +10 -4
  164. package/templates/base/tools/testin-nutin/core/queue/test-queue.js.hbs +8 -8
  165. package/templates/base/tools/testin-nutin/mocks/mock-event-bus.js.hbs +27 -25
  166. package/templates/base/tools/testin-nutin/mocks/mock-event-bus.test.js.hbs +30 -22
  167. package/templates/base/tools/testin-nutin/mocks/mock-http-client.js.hbs +7 -10
  168. package/templates/base/tools/testin-nutin/mocks/mock-http-client.test.js.hbs +12 -0
  169. package/templates/base/tools/testin-nutin/mocks/mock-i18n.js.hbs +47 -22
  170. package/templates/base/tools/testin-nutin/mocks/mock-i18n.test.js.hbs +47 -26
  171. package/templates/base/tools/testin-nutin/mocks/mock-router.js.hbs +19 -11
  172. package/templates/base/tools/testin-nutin/mocks/mock-router.test.js.hbs +24 -7
  173. package/templates/base/tools/testin-nutin/runner.js.hbs +12 -3
  174. package/templates/base/tools/testin-nutin/watch-tests.js.hbs +45 -20
  175. package/templates/base/tools/utils/build-lock.js.hbs +30 -2
  176. package/templates/base/tools/utils/ensure-deps.js.hbs +72 -0
  177. package/templates/base/tools/utils/ensure-deps.test.js.hbs +17 -0
  178. package/templates/base/tools/utils/format.js.hbs +1 -1
  179. package/templates/base/tools/utils/index.js.hbs +2 -1
  180. package/templates/base/tools/utils/print.js.hbs +2 -2
  181. package/templates/base/tools/utils/resolve-port.js.hbs +30 -0
  182. package/templates/base/tools/utils/resolve-port.test.js.hbs +47 -0
  183. package/templates/base/tools/utils/run-command.js.hbs +30 -1
  184. package/templates/base/tools/utils/run-command.test.js.hbs +12 -1
  185. package/templates/base/tools/utils/run-script.js.hbs +2 -2
  186. package/templates/features/docker/tools/docker/Dockerfile.template.hbs +3 -0
  187. package/templates/features/docker/tools/docker/nginx.conf.template +6 -4
  188. package/templates/features/docker/tools/docker/scripts/docker-ports.js.hbs +1 -1
  189. package/templates/features/docker/tools/docker/scripts/docker-ports.test.js.hbs +2 -2
  190. package/templates/features/docker/tools/docker/scripts/locale-redirects.js.hbs +28 -0
  191. package/templates/features/docker/tools/docker/scripts/locale-redirects.test.js.hbs +34 -0
  192. package/templates/features/docker/tools/docker/scripts/markdown-sources-copy.js.hbs +25 -0
  193. package/templates/features/docker/tools/docker/scripts/markdown-sources-copy.test.js.hbs +34 -0
  194. package/templates/features/docker/tools/docker/scripts/render-docker-template.js.hbs +3 -1
  195. package/templates/features/docker/tools/docker/scripts/render-docker-template.test.js.hbs +12 -0
  196. package/templates/features/docker/tools/docker/scripts/validate-docker.js.hbs +21 -4
  197. package/templates/features/markdown/markdown-content/getting-started.md.hbs +28 -0
  198. package/templates/features/markdown/markdown-content/writing-pages.md.hbs +19 -0
  199. package/templates/features/markdown/src/app/markdown/components/markdown-content/markdown-content.component.scss.hbs +75 -0
  200. package/templates/features/markdown/src/app/markdown/components/markdown-content/markdown-content.component.test.js.hbs +40 -0
  201. package/templates/features/markdown/src/app/markdown/components/markdown-content/markdown-content.component.ts.hbs +65 -0
  202. package/templates/features/markdown/src/app/markdown/components/markdown-landing/markdown-landing.component.test.js.hbs +67 -0
  203. package/templates/features/markdown/src/app/markdown/components/markdown-landing/markdown-landing.component.ts.hbs +87 -0
  204. package/templates/features/markdown/src/app/markdown/components/markdown-nav/markdown-nav.component.scss.hbs +42 -0
  205. package/templates/features/markdown/src/app/markdown/components/markdown-nav/markdown-nav.component.test.js.hbs +59 -0
  206. package/templates/features/markdown/src/app/markdown/components/markdown-nav/markdown-nav.component.ts.hbs +72 -0
  207. package/templates/features/markdown/src/app/markdown/locales/en.json.hbs +6 -0
  208. package/templates/features/markdown/src/app/markdown/markdown-guards.test.js.hbs +63 -0
  209. package/templates/features/markdown/src/app/markdown/markdown-guards.ts.hbs +31 -0
  210. package/templates/features/markdown/src/app/markdown/markdown-i18n.test.js.hbs +78 -0
  211. package/templates/features/markdown/src/app/markdown/markdown-i18n.ts.hbs +31 -0
  212. package/templates/features/markdown/src/app/markdown/markdown-manifest.test.js.hbs +98 -0
  213. package/templates/features/markdown/src/app/markdown/markdown-manifest.ts.hbs +157 -0
  214. package/templates/features/markdown/src/app/markdown/markdown-manifests.service.test.js.hbs +87 -0
  215. package/templates/features/markdown/src/app/markdown/markdown-manifests.service.ts.hbs +50 -0
  216. package/templates/features/markdown/src/app/markdown/markdown-routes.test.js.hbs +74 -0
  217. package/templates/features/markdown/src/app/markdown/markdown-routes.ts.hbs +26 -0
  218. package/templates/features/markdown/src/app/markdown/markdown-sources.test.js.hbs +22 -0
  219. package/templates/features/markdown/src/app/markdown/markdown-sources.ts.hbs +42 -0
  220. package/templates/features/markdown/src/app/markdown/view/markdown.view.html.hbs +4 -0
  221. package/templates/features/markdown/src/app/markdown/view/markdown.view.scss.hbs +19 -0
  222. package/templates/features/markdown/src/app/markdown/view/markdown.view.test.js.hbs +125 -0
  223. package/templates/features/markdown/src/app/markdown/view/markdown.view.ts.hbs +146 -0
  224. package/templates/features/markdown/tools/builder/core/markdown/generate-markdown-pages.js.hbs +71 -0
  225. package/templates/features/markdown/tools/builder/core/markdown/markdown-compiler.js.hbs +582 -0
  226. package/templates/features/markdown/tools/builder/core/markdown/markdown-compiler.test.js.hbs +390 -0
  227. package/templates/features/markdown/tools/builder/core/markdown/markdown-seo-routes.js.hbs +155 -0
  228. package/templates/features/markdown/tools/builder/core/markdown/markdown-seo-routes.test.js.hbs +112 -0
  229. /package/templates/base/tools/testin-nutin/core/{tests → globals}/clock.test.js.hbs +0 -0
@@ -27,9 +27,13 @@ src/
27
27
 
28
28
  tools/ -- build, development, generator and testing
29
29
 
30
- nutin.config.js -- features and configuration
30
+ nutin.config.js -- options and configuration
31
31
  ```
32
32
 
33
+ * Views **orchestrate application flow**
34
+ * Components **encapsulate UI behavior**
35
+ * Services **handle application concerns** through shared instances
36
+
33
37
  ### Imports
34
38
 
35
39
  - Imports use **relative paths** and end with `.js` extension.
@@ -39,6 +43,9 @@ import { Foo } from 'relative/path/to/foo.js';
39
43
  ```
40
44
 
41
45
  - Use Nutin's code barrel file (`src/core/index.js`) to import Nutin's modules.
46
+ {{#if (eq lang "ts")}}
47
+ - Nutin's types (`Nutin.ComponentConfig`, `Nutin.Routes`, `Nutin.Template`, …) live in the global `Nutin` namespace declared in `src/core/internals.d.ts`: no import needed.
48
+ {{/if}}
42
49
 
43
50
  ## How do I run my app?
44
51
 
@@ -46,6 +53,7 @@ import { Foo } from 'relative/path/to/foo.js';
46
53
  # Development
47
54
  {{packageManager}} run serve # build and serve
48
55
  {{packageManager}} run dev # build and serve with live reload
56
+ {{packageManager}} run dev -- --port 3000 # serve on another port (default 9090; PORT=3000 also works)
49
57
 
50
58
  # Build
51
59
  {{packageManager}} run build # build the application
@@ -60,13 +68,10 @@ Elements are generated in `src/app/<path>/`, so you choose the project structure
60
68
  {{packageManager}} run generate <component|view|service> PATH/TO/ELEMENT_NAME
61
69
 
62
70
  # Examples
63
- {{packageManager}} run generate component components/my-component # Target dir: src/app/components/my-component/
64
- {{packageManager}} run generate view user/user-view # Target dir: src/app/user/user-view/
65
- {{packageManager}} run generate service user/user-service # Target dir: src/app/user/user-service/
71
+ {{packageManager}} run generate component components/hello-world # generates src/app/components/hello-world/hello-world.component.ts|html|scss
72
+ {{packageManager}} run generate view user/dashboard # generates src/app/user/dashboard/dashboard.view.ts|html|scss
66
73
  ```
67
74
 
68
- Import generated elements by their file path (e.g. `./views/home/home.view.js`).
69
-
70
75
  ## What does a typical component look like?
71
76
 
72
77
  ```bash
@@ -78,8 +83,8 @@ components/
78
83
  ```
79
84
 
80
85
  ```ts
81
- // The builder injects the component's .html template here.
82
- const templateFn = (product: Product) => `__TEMPLATE_PLACEHOLDER__`;
86
+ // The component's .html template is injected here.
87
+ const templateFn = (product: Product) => html`__TEMPLATE_PLACEHOLDER__`;
83
88
 
84
89
  export class ProductCardComponent extends Component {
85
90
  private _product: Product;
@@ -90,7 +95,7 @@ export class ProductCardComponent extends Component {
90
95
  }
91
96
 
92
97
  // Declares children mounted into the data-component / data-catalog placeholders below.
93
- public registerChildren(): ComponentConfig[] {
98
+ public registerChildren(): Nutin.ComponentConfig[] {
94
99
  // Single child, matched to <div data-component="product-details">
95
100
  const detailsComponent = {
96
101
  selector: `product-details`,
@@ -123,7 +128,8 @@ export class ProductCardComponent extends Component {
123
128
 
124
129
  ```html
125
130
  <div
126
- data-event="click:_goToProductPage:${product.id}"
131
+ data-product-id="${product.id}"
132
+ data-event="click:_goToProductPage:@dataset:productId"
127
133
  class="product-card"
128
134
  >
129
135
  <h2 class="product-card__name">${product.name}</h2>
@@ -150,12 +156,12 @@ Defining both an inline template and an external `.html` file, or neither, fails
150
156
 
151
157
  ### Main file
152
158
 
153
- `nutin.config.js` - Main Nutin configuration and tool options. See the inline comments for details.
159
+ `nutin.config.js` - Main Nutin configuration and tool options. See the inline comments and [How do I configure Nutin?](https://www.nutin.dev/docs/options-and-features/configure-nutin) for details.
160
+
161
+ This is where you can:
154
162
 
155
- - `tailwind`, `i18n`, `generateSEOFiles` — top-level features, `false` by default.
156
- See [Options and features](https://github.com/LoisKOUNINEF/nutin/tree/main/docs/OPTIONS_AND_FEATURES.md).
157
- - `builder.*` — controls build behavior.
158
- - `testinNutin.*` — controls Nutin's built-in testing toolkit.
163
+ - Toggle options ([Tailwind CSS](https://www.nutin.dev/docs/options-and-features/use-tailwind-css), [i18n](https://www.nutin.dev/docs/options-and-features/use-i18n), [SEO file generation](https://www.nutin.dev/docs/options-and-features/use-seo-file-generation)).
164
+ - Configure the builder and the built-in testing toolkit.
159
165
 
160
166
  ### Specialized files
161
167
 
@@ -174,7 +180,7 @@ See [Options and features](https://github.com/LoisKOUNINEF/nutin/tree/main/docs/
174
180
 
175
181
  You can use any testing tool you prefer for application code.
176
182
 
177
- 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:
183
+ This project includes [testin-nutin](https://www.nutin.dev/docs/testing), Nutin's small testing toolkit. Nutin itself is tested exclusively with it, and the tests are included in the generated project so you can:
178
184
  - use them as executable documentation;
179
185
  - run and modify Nutin's tests when modifying its code.
180
186
 
@@ -190,13 +196,13 @@ testinNutin: {
190
196
  includeApp: true,
191
197
  }
192
198
  ```
193
- *Note:* TestinNutin files use root imports.
199
+ *Note:* TestinNutin files are plain JavaScript and use root imports{{#if (eq lang "ts")}}: they test the compiled output, so they aren't type-checked{{/if}}.
194
200
  ```js
195
201
  import { MyModule } from '#root/dist/src/path/to/my-module.js';
196
202
  ```
197
203
 
198
204
  ## Go further
199
205
 
200
- - [Repository documentation](https://github.com/LoisKOUNINEF/nutin/tree/main/docs/API.md)
201
- - [First app tutorial](https://www.nutin.org/tutorial)
202
- - [Nutin website](https://www.nutin.org)
206
+ - [Documentation](https://www.nutin.dev/docs)
207
+ - [First app tutorial](https://www.nutin.dev/tutorial)
208
+ - [Nutin website](https://www.nutin.dev)
@@ -2,13 +2,16 @@
2
2
 
3
3
  ## Development
4
4
 
5
- - `{{packageManager}} run serve` — build and serve
6
- - `{{packageManager}} run dev` — build and serve with live reload
5
+ Requires Node.js 24 or later.
6
+
7
+ - `{{packageManager}} run serve`: build and serve
8
+ - `{{packageManager}} run dev`: build and serve with live reload
9
+ - Both serve on port 9090 by default. Pass `-- --port 3000` (or set `PORT=3000`) to change it
7
10
 
8
11
  ## Build
9
12
 
10
- - `{{packageManager}} run build` — build the application
11
- - `{{packageManager}} run build:prod` — build the application for production
13
+ - `{{packageManager}} run build`: build the application
14
+ - `{{packageManager}} run build:prod`: build the application for production
12
15
 
13
16
  ## Getting started
14
17
 
@@ -1,4 +1,7 @@
1
- declare interface AppEventMap {
1
+ declare namespace Nutin {
2
+ interface AppEventMap {
2
3
  // Add app-specific event types here
3
- // 'event': { /* payload? */ }
4
- };
4
+ // 'task-saved': { taskId: number }; // emit('task-saved', { taskId }) — payload required
5
+ // 'tasks-cleared': undefined; // emit('tasks-cleared') — no payload
6
+ }
7
+ }
@@ -1,10 +1,8 @@
1
- import { RouteGuard } from "../core/index.js";
2
-
3
1
  export const Guards = {
4
2
  /**
5
3
  * Basic example
6
4
  */
7
- requireAuth: (redirectTo: string = '/login'): RouteGuard => {
5
+ requireAuth: (redirectTo: string = '/login'): Nutin.RouteGuard => {
8
6
  return () => {
9
7
  const isAuthenticated = !!localStorage.getItem('user_token');
10
8
  return isAuthenticated || redirectTo;
@@ -1,5 +1,4 @@
1
- import nutinConfig from '../../nutin.config.js';
2
- import { AppRouter, Service, I18nService, registerPipes } from '../core/index.js';
1
+ import { AppRouter, initI18n, registerPipes } from '../core/index.js';
3
2
  import { appRoutes } from './routes.js';
4
3
 
5
4
  class App {
@@ -10,12 +9,6 @@ class App {
10
9
  }
11
10
 
12
11
  document.addEventListener('DOMContentLoaded', async () => {
13
- if (nutinConfig.i18n) {
14
- await I18nService.initTranslations();
15
- }
12
+ await initI18n();
16
13
  new App();
17
14
  });
18
-
19
- window.addEventListener('beforeunload', async () => {
20
- await Service.destroyAll();
21
- });
@@ -1,8 +1,13 @@
1
- import { Routes } from '../core/index.js';
2
1
  import { HomeView } from './views/home/home.view.js';
3
2
  import { NotFoundView } from './views/not-found/not-found.view.js';
3
+ {{#if markdown}}
4
+ import { markdownRoutes } from './markdown/markdown-routes.js';
5
+ {{/if}}
4
6
 
5
- export const appRoutes: Routes = {
7
+ export const appRoutes: Nutin.Routes = {
6
8
  '/': () => new HomeView(),
9
+ {{#if markdown}}
10
+ ...markdownRoutes(),
11
+ {{/if}}
7
12
  '/404': () => new NotFoundView(),
8
13
  }
@@ -3,5 +3,5 @@
3
3
  <span style="font-style:italic;font-size:clamp(.6875rem,2vw,1rem);">nutin v{{version}}</span>
4
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
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>
6
+ <div style="font-size:clamp(.75rem,2vw,1rem);font-style:italic;position:fixed;bottom:0;padding-bottom:.2rem;">it's <span style="font-weight:bold;"><a style="text-decoration:none;color:#6C8359;" href="https://nutin.dev">nutin</a></span>.</div>
7
7
  </div>
@@ -1,6 +1,6 @@
1
- import { View } from '../../../core/index.js';
1
+ import { View, html } from '../../../core/index.js';
2
2
 
3
- const template = `__TEMPLATE_PLACEHOLDER__`;
3
+ const template = html`__TEMPLATE_PLACEHOLDER__`;
4
4
 
5
5
  export class HomeView extends View {
6
6
  constructor() {
@@ -1,6 +1,6 @@
1
- import { Navigation, View } from '../../../core/index.js';
1
+ import { Navigation, View, html } from '../../../core/index.js';
2
2
 
3
- const template = `__TEMPLATE_PLACEHOLDER__`;
3
+ const template = html`__TEMPLATE_PLACEHOLDER__`;
4
4
 
5
5
  export class NotFoundView extends View {
6
6
  constructor() {