@nitra/cursor 12.8.6 → 12.8.8

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 (263) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/package.json +1 -1
  3. package/rules/abie/main.mdc +9 -5
  4. package/rules/abie/policy/base_deployment_preem/base_deployment_preem.mdc +22 -0
  5. package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
  6. package/rules/abie/policy/health_check_policy/health_check_policy.mdc +17 -0
  7. package/rules/abie/policy/http_route_base/http_route_base.mdc +9 -0
  8. package/rules/abie/policy/package_json_shared/package_json_shared.mdc +17 -0
  9. package/rules/adr/js/hooks.mdc +32 -0
  10. package/rules/adr/js/madr_format.mdc +96 -0
  11. package/rules/adr/js/settings_policy.mdc +34 -0
  12. package/rules/adr/main.mdc +17 -95
  13. package/rules/adr/policy/settings_json/settings_json.mdc +7 -0
  14. package/rules/adr/policy/settings_local_json/settings_local_json.mdc +7 -0
  15. package/rules/bun/js/bunfig.mdc +12 -0
  16. package/rules/bun/js/layout.mdc +60 -0
  17. package/rules/bun/js/lint.mdc +9 -0
  18. package/rules/bun/js/package_json.mdc +19 -0
  19. package/rules/bun/main.mdc +7 -60
  20. package/rules/bun/policy/bunfig/bunfig.mdc +12 -0
  21. package/rules/bun/policy/package_json/package_json.mdc +14 -0
  22. package/rules/capacitor/js/ios_spm.mdc +69 -0
  23. package/rules/capacitor/js/version.mdc +29 -0
  24. package/rules/capacitor/main.mdc +6 -22
  25. package/rules/capacitor/policy/package_json/package_json.mdc +9 -0
  26. package/rules/changelog/js/agent-workflow.mdc +15 -0
  27. package/rules/changelog/js/changelog-format.mdc +33 -0
  28. package/rules/changelog/js/comparison-models.mdc +40 -0
  29. package/rules/changelog/main.mdc +4 -98
  30. package/rules/ci4/js/marksman_config.mdc +31 -0
  31. package/rules/ci4/js/vscode_extensions.mdc +33 -0
  32. package/rules/ci4/main.mdc +16 -14
  33. package/rules/ci4/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  34. package/rules/docker/js/compile.mdc +44 -0
  35. package/rules/docker/js/hadolint.mdc +50 -0
  36. package/rules/docker/js/mirror.mdc +13 -0
  37. package/rules/docker/js/multistage.mdc +13 -0
  38. package/rules/docker/js/native-addon.mdc +43 -0
  39. package/rules/docker/js/nginx-tag.mdc +7 -0
  40. package/rules/docker/js/nginx-user.mdc +37 -0
  41. package/rules/docker/js/non-root.mdc +39 -0
  42. package/rules/docker/main.mdc +13 -196
  43. package/rules/docker/policy/lint_docker_yml/lint_docker_yml.mdc +14 -0
  44. package/rules/efes/main.mdc +1 -1
  45. package/rules/efes/policy/package_json_shared/package_json_shared.mdc +30 -0
  46. package/rules/ga/js/lint_toolchain.mdc +15 -0
  47. package/rules/ga/js/required_workflows.mdc +35 -0
  48. package/rules/ga/js/vscode.mdc +17 -0
  49. package/rules/ga/js/workflow_common.mdc +108 -0
  50. package/rules/ga/js/workflows.mdc +32 -0
  51. package/rules/ga/js/zizmor.mdc +7 -0
  52. package/rules/ga/main.mdc +16 -119
  53. package/rules/ga/policy/clean_ga_workflows/clean_ga_workflows.mdc +18 -0
  54. package/rules/ga/policy/clean_merged_branch/clean_merged_branch.mdc +22 -0
  55. package/rules/ga/policy/git_ai/git_ai.mdc +19 -0
  56. package/rules/ga/policy/lint_ga/lint_ga.mdc +21 -0
  57. package/rules/ga/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  58. package/rules/ga/policy/vscode_settings/vscode_settings.mdc +9 -0
  59. package/rules/ga/policy/workflow_common/workflow_common.mdc +18 -0
  60. package/rules/ga/policy/zizmor_yml/zizmor_yml.mdc +9 -0
  61. package/rules/graphql/js/tooling.mdc +13 -0
  62. package/rules/graphql/js/vscode_extensions.mdc +13 -0
  63. package/rules/graphql/main.mdc +4 -21
  64. package/rules/graphql/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  65. package/rules/hasura/js/internal_urls.mdc +27 -0
  66. package/rules/hasura/js/migrations.mdc +13 -0
  67. package/rules/hasura/js/svc_hl.mdc +17 -0
  68. package/rules/hasura/main.mdc +6 -30
  69. package/rules/hasura/policy/svc_hl/svc_hl.mdc +15 -0
  70. package/rules/image-avif/js/avif_generation.mdc +26 -0
  71. package/rules/image-avif/js/package_json_optout.mdc +21 -0
  72. package/rules/image-avif/main.mdc +5 -34
  73. package/rules/image-avif/policy/package_json/package_json.mdc +18 -0
  74. package/rules/image-compress/js/package_json.mdc +7 -0
  75. package/rules/image-compress/js/package_setup.mdc +13 -0
  76. package/rules/image-compress/main.mdc +4 -12
  77. package/rules/image-compress/policy/package_json/package_json.mdc +13 -0
  78. package/rules/js/docs/index.md +3 -3
  79. package/rules/js/js/dep-policy.mdc +17 -0
  80. package/rules/js/js/eslint-config.mdc +28 -0
  81. package/rules/js/js/extensions.mdc +8 -0
  82. package/rules/js/js/file-extensions.mdc +12 -0
  83. package/rules/js/js/for-in.mdc +26 -0
  84. package/rules/js/js/jscpd.mdc +42 -0
  85. package/rules/js/js/knip.mdc +15 -0
  86. package/rules/js/js/lint-js-workflow.mdc +58 -0
  87. package/rules/js/js/oxlintrc.mdc +20 -0
  88. package/rules/js/js/package-json.mdc +31 -0
  89. package/rules/js/js/tests.mdc +9 -0
  90. package/rules/js/js/utils-lib-structure.mdc +15 -0
  91. package/rules/js/main.mdc +19 -211
  92. package/rules/js/policy/jscpd/jscpd.mdc +14 -0
  93. package/rules/js/policy/lint_js_yml/lint_js_yml.mdc +14 -0
  94. package/rules/js/policy/package_json/package_json.mdc +15 -0
  95. package/rules/js/policy/vscode_extensions/vscode_extensions.mdc +11 -0
  96. package/rules/js-bun-db/js/bun-sql-migration.mdc +15 -0
  97. package/rules/js-bun-db/js/connection.mdc +42 -0
  98. package/rules/js-bun-db/js/pg-format-identifiers.mdc +102 -0
  99. package/rules/js-bun-db/js/pg-format-shim.mdc +99 -0
  100. package/rules/js-bun-db/js/pg-leftover.mdc +27 -0
  101. package/rules/js-bun-db/js/pg-listen-notify.mdc +51 -0
  102. package/rules/js-bun-db/js/query-safety.mdc +117 -0
  103. package/rules/js-bun-db/js/sql-array.mdc +88 -0
  104. package/rules/js-bun-db/js/unsafe.mdc +65 -0
  105. package/rules/js-bun-db/main.mdc +12 -607
  106. package/rules/js-bun-db/policy/package_json/package_json.mdc +17 -0
  107. package/rules/js-bun-redis/js/imports.mdc +47 -0
  108. package/rules/js-bun-redis/js/package_json.mdc +44 -0
  109. package/rules/js-bun-redis/main.mdc +4 -10
  110. package/rules/js-bun-redis/policy/package_json/package_json.mdc +11 -0
  111. package/rules/js-mssql/js/mssql-in-list.mdc +38 -0
  112. package/rules/js-mssql/js/mssql-pool.mdc +56 -0
  113. package/rules/js-mssql/js/mssql-query-template.mdc +33 -0
  114. package/rules/js-mssql/js/mssql-tvp.mdc +75 -0
  115. package/rules/js-mssql/js/mssql-version.mdc +7 -0
  116. package/rules/js-mssql/main.mdc +10 -198
  117. package/rules/js-mssql/policy/package_json/package_json.mdc +9 -0
  118. package/rules/js-run/js/check-env.mdc +35 -0
  119. package/rules/js-run/js/conn-aliases.mdc +109 -0
  120. package/rules/js-run/js/jsconfig.mdc +20 -0
  121. package/rules/js-run/js/otel-configmap.mdc +6 -0
  122. package/rules/js-run/js/pino.mdc +6 -0
  123. package/rules/js-run/js/project-structure.mdc +11 -0
  124. package/rules/js-run/js/runtime.mdc +14 -0
  125. package/rules/js-run/js/scope.mdc +11 -0
  126. package/rules/js-run/js/settimeout.mdc +11 -0
  127. package/rules/js-run/js/temporal.mdc +5 -0
  128. package/rules/js-run/main.mdc +16 -216
  129. package/rules/js-run/policy/configmap/configmap.mdc +31 -0
  130. package/rules/js-run/policy/jsconfig/jsconfig.mdc +25 -0
  131. package/rules/js-run/policy/package_json/package_json.mdc +38 -0
  132. package/rules/k8s/js/configmap.mdc +41 -0
  133. package/rules/k8s/js/deployment_resources.mdc +49 -0
  134. package/rules/k8s/js/hasura_httproute.mdc +91 -0
  135. package/rules/k8s/js/hpa_apiversion.mdc +27 -0
  136. package/rules/k8s/js/ingress_gateway.mdc +16 -0
  137. package/rules/k8s/js/kustomize_structure.mdc +144 -0
  138. package/rules/k8s/js/lint_k8s.mdc +72 -0
  139. package/rules/k8s/js/multidoc_yaml.mdc +5 -0
  140. package/rules/k8s/js/network_policy.mdc +136 -0
  141. package/rules/k8s/js/schema_modeline.mdc +57 -0
  142. package/rules/k8s/js/service.mdc +44 -0
  143. package/rules/k8s/js/topology_hpa_pdb.mdc +181 -0
  144. package/rules/k8s/main.mdc +29 -834
  145. package/rules/k8s/policy/base_kustomization/base_kustomization.mdc +12 -0
  146. package/rules/k8s/policy/base_manifest/base_manifest.mdc +14 -0
  147. package/rules/k8s/policy/gateway/gateway.mdc +17 -0
  148. package/rules/k8s/policy/hasura_configmap/hasura_configmap.mdc +20 -0
  149. package/rules/k8s/policy/hasura_httproute/hasura_httproute.mdc +16 -0
  150. package/rules/k8s/policy/hpa_pdb/hpa_pdb.mdc +23 -0
  151. package/rules/k8s/policy/kustomization/kustomization.mdc +20 -0
  152. package/rules/k8s/policy/manifest/manifest.mdc +17 -0
  153. package/rules/k8s/policy/network_policy/network_policy.mdc +22 -0
  154. package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
  155. package/rules/k8s/policy/svc_yaml/svc_yaml.mdc +12 -0
  156. package/rules/nginx-default-tpl/js/dockerfile.mdc +36 -0
  157. package/rules/nginx-default-tpl/js/http-route.mdc +41 -0
  158. package/rules/nginx-default-tpl/js/ini-keys.mdc +21 -0
  159. package/rules/nginx-default-tpl/js/template-structure.mdc +86 -0
  160. package/rules/nginx-default-tpl/js/vscode.mdc +37 -0
  161. package/rules/nginx-default-tpl/main.mdc +8 -110
  162. package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions.mdc +11 -0
  163. package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings.mdc +15 -0
  164. package/rules/npm-module/js/docs/index.md +5 -5
  165. package/rules/npm-module/js/docs/rule_meta.md +6 -6
  166. package/rules/npm-module/js/docs/skill_meta.md +8 -8
  167. package/rules/npm-module/js/header_doc_pointer.mdc +18 -0
  168. package/rules/npm-module/js/package_structure.mdc +62 -0
  169. package/rules/npm-module/js/rule_meta.mdc +11 -0
  170. package/rules/npm-module/js/skill_meta.mdc +11 -0
  171. package/rules/npm-module/main.mdc +10 -52
  172. package/rules/npm-module/policy/emit_types_config/emit_types_config.mdc +40 -0
  173. package/rules/npm-module/policy/npm_package_json/npm_package_json.mdc +50 -0
  174. package/rules/npm-module/policy/root_package_json/root_package_json.mdc +37 -0
  175. package/rules/php/js/lint_php_yml.mdc +12 -0
  176. package/rules/php/js/tooling.mdc +66 -0
  177. package/rules/php/main.mdc +5 -66
  178. package/rules/php/policy/lint_php_yml/lint_php_yml.mdc +21 -0
  179. package/rules/python/js/lint_python_yml.mdc +23 -0
  180. package/rules/python/js/pyproject_toml.mdc +32 -0
  181. package/rules/python/js/tooling.mdc +23 -0
  182. package/rules/python/main.mdc +7 -32
  183. package/rules/python/policy/lint_python_yml/lint_python_yml.mdc +12 -0
  184. package/rules/python/policy/pyproject_toml/pyproject_toml.mdc +13 -0
  185. package/rules/rego/js/rego-lint.mdc +31 -0
  186. package/rules/rego/js/vscode_extensions.mdc +11 -0
  187. package/rules/rego/js/vscode_settings.mdc +13 -0
  188. package/rules/rego/main.mdc +10 -22
  189. package/rules/rego/policy/vscode_extensions/vscode_extensions.mdc +11 -0
  190. package/rules/rego/policy/vscode_settings/vscode_settings.mdc +19 -0
  191. package/rules/rust/js/coverage.mdc +28 -0
  192. package/rules/rust/js/lint.mdc +22 -0
  193. package/rules/rust/js/tauri_composition.mdc +8 -0
  194. package/rules/rust/js/vscode_extensions.mdc +12 -0
  195. package/rules/rust/main.mdc +8 -38
  196. package/rules/rust/policy/lint_rust_yml/lint_rust_yml.mdc +12 -0
  197. package/rules/rust/policy/vscode_extensions/vscode_extensions.mdc +9 -0
  198. package/rules/security/js/rego_policies.mdc +15 -0
  199. package/rules/security/js/sample_secret.mdc +19 -0
  200. package/rules/security/js/trufflehog.mdc +21 -0
  201. package/rules/security/main.mdc +7 -34
  202. package/rules/security/policy/lint_security_yml/lint_security_yml.mdc +7 -0
  203. package/rules/security/policy/package_json/package_json.mdc +7 -0
  204. package/rules/style/js/admin-table.mdc +88 -0
  205. package/rules/style/js/colors.mdc +21 -0
  206. package/rules/style/js/gap.mdc +22 -0
  207. package/rules/style/js/quasar-fixes.mdc +32 -0
  208. package/rules/style/js/quasar.mdc +7 -0
  209. package/rules/style/js/tooling.mdc +85 -0
  210. package/rules/style/main.mdc +12 -251
  211. package/rules/style/policy/lint_style_yml/lint_style_yml.mdc +13 -0
  212. package/rules/style/policy/package_json/package_json.mdc +18 -0
  213. package/rules/style/policy/vscode_extensions/vscode_extensions.mdc +13 -0
  214. package/rules/style/policy/vscode_settings/vscode_settings.mdc +19 -0
  215. package/rules/tauri/js/cargo_mutants_config.mdc +39 -0
  216. package/rules/tauri/js/tool_surface.mdc +21 -0
  217. package/rules/tauri/js/tooling.mdc +25 -0
  218. package/rules/tauri/main.mdc +6 -78
  219. package/rules/tauri/policy/vscode_extensions/vscode_extensions.mdc +21 -0
  220. package/rules/test/js/cargo_mutants_config.mdc +18 -0
  221. package/rules/test/js/docs/index.md +7 -7
  222. package/rules/test/js/location.mdc +52 -0
  223. package/rules/test/js/no-console-store-restore.mdc +11 -0
  224. package/rules/test/js/no-process-chdir.mdc +15 -0
  225. package/rules/test/js/no-relative-fs-path.mdc +22 -0
  226. package/rules/test/js/sandbox-aware-test.mdc +28 -0
  227. package/rules/test/js/stryker_config.mdc +26 -0
  228. package/rules/test/js/vitest-config-pool-forks.mdc +33 -0
  229. package/rules/test/main.mdc +16 -184
  230. package/rules/test/policy/package_json/package_json.mdc +16 -0
  231. package/rules/text/js/ci-lint-text.mdc +15 -0
  232. package/rules/text/js/cspell.mdc +81 -0
  233. package/rules/text/js/dotenv-linter.mdc +16 -0
  234. package/rules/text/js/forbidden-prettier.mdc +13 -0
  235. package/rules/text/js/markdownlint.mdc +25 -0
  236. package/rules/text/js/oxfmt.mdc +35 -0
  237. package/rules/text/js/package-json.mdc +26 -0
  238. package/rules/text/js/shellcheck.mdc +18 -0
  239. package/rules/text/js/v8r.mdc +23 -0
  240. package/rules/text/js/vscode.mdc +86 -0
  241. package/rules/text/main.mdc +20 -231
  242. package/rules/text/policy/cspell/cspell.mdc +34 -0
  243. package/rules/text/policy/lint_text/lint_text.mdc +19 -0
  244. package/rules/text/policy/markdownlint/markdownlint.mdc +38 -0
  245. package/rules/text/policy/oxfmtrc/oxfmtrc.mdc +11 -0
  246. package/rules/text/policy/package_json/package_json.mdc +33 -0
  247. package/rules/text/policy/vscode_extensions/vscode_extensions.mdc +13 -0
  248. package/rules/text/policy/vscode_settings/vscode_settings.mdc +13 -0
  249. package/rules/vue/js/composition-api.mdc +82 -0
  250. package/rules/vue/js/nheader-layout.mdc +171 -0
  251. package/rules/vue/js/node-imports.mdc +25 -0
  252. package/rules/vue/js/quasar-ui.mdc +32 -0
  253. package/rules/vue/js/structure.mdc +101 -0
  254. package/rules/vue/js/testing.mdc +32 -0
  255. package/rules/vue/js/tfm-translations.mdc +26 -0
  256. package/rules/vue/js/vite-config.mdc +126 -0
  257. package/rules/vue/js/vite-env.mdc +55 -0
  258. package/rules/vue/js/vue-imports.mdc +25 -0
  259. package/rules/vue/main.mdc +15 -641
  260. package/rules/vue/policy/package_json/package_json.mdc +30 -0
  261. package/scripts/docs/index.md +16 -16
  262. package/scripts/lib/docs/index.md +36 -36
  263. package/scripts/utils/docs/index.md +14 -14
@@ -0,0 +1,171 @@
1
+ ## NHeader — телепорт-слоти на сторінках
2
+
3
+ У проектах з `NHeader` використовуй `<teleport>` для вбудовування контенту сторінки в шапку:
4
+
5
+ | Слот | Призначення |
6
+ | --- | --- |
7
+ | `#header-subtitle` | Заголовок сторінки (якщо потрібно перевизначити subtitle) |
8
+ | `#header-center` | Важливі повідомлення та елементи управління |
9
+ | `#header-filters` | Фільтри, кнопки та інші елементи управління сторінки |
10
+
11
+ Оскільки `NHeader` за замовчуванням темний, додавай до полів і селектів у телепортах: `dark`, `standout="bg-white text-primary"`, `:options-dark="false"`.
12
+
13
+ Завжди обгортай `<teleport>` в `v-if="mounted"` (де `mounted` — `$ref(false)`, що встановлюється в `onMounted`), щоб уникнути помилки відсутності target-елемента при SSR / першому рендері.
14
+
15
+ ```vue
16
+ <template>
17
+ <q-page>
18
+ <!-- ФІЛЬТРИ В ШАПЦІ -->
19
+ <teleport v-if="mounted" to="#header-filters">
20
+ <div class="col row items-center n-gap-sm q-pa-sm">
21
+ <q-input
22
+ v-model="pageStore.filterName"
23
+ :label="t`Поиск по названию`"
24
+ debounce="200"
25
+ standout="bg-white text-primary"
26
+ clearable
27
+ dense
28
+ dark
29
+ class="col"
30
+ style="min-width: 120px">
31
+ <template #prepend>
32
+ <q-icon name="search" />
33
+ </template>
34
+ </q-input>
35
+
36
+ <n-select-multi
37
+ v-model="pageStore.filterRequestTypes"
38
+ :options="requestTypeOptions"
39
+ :label="t`Тип запроса`"
40
+ dark
41
+ standout="bg-white text-primary"
42
+ :options-dark="false"
43
+ style="min-width: 180px; max-width: 400px"
44
+ dense
45
+ emit-value
46
+ map-options
47
+ clearable
48
+ searchable
49
+ :stack-label="false" />
50
+
51
+ <q-btn
52
+ @click="addItem"
53
+ icon="add"
54
+ :label="t`Добавить`"
55
+ color="primary"
56
+ no-caps
57
+ padding="8px 12px"
58
+ unelevated />
59
+ </div>
60
+ </teleport>
61
+
62
+ <!-- ОСНОВНИЙ КОНТЕНТ -->
63
+ ...
64
+ </q-page>
65
+ </template>
66
+ <script setup>
67
+ const mounted = $ref(false)
68
+ onMounted(() => { mounted = true })
69
+ </script>
70
+ ```
71
+
72
+ ## Layout з NHeader
73
+
74
+ Для нових layout-ів використовуй `NHeader` з вбудованими `NLang` і `NMenu`.
75
+
76
+ ```vue
77
+ <template>
78
+ <q-layout view="hHh Lpr lFf">
79
+ <n-header
80
+ v-model="leftSideOpened"
81
+ :logo="baseUrl + 'logo.png'"
82
+ :logo-url="homeUrl"
83
+ title="My App"
84
+ :subtitle="subtitle"
85
+ :username="userName"
86
+ toolbar-dark>
87
+ <template #top-toolbar>
88
+ <div class="platform-ios-only q-py-lg" />
89
+ </template>
90
+ <div>default slot content</div>
91
+ </n-header>
92
+
93
+ <!-- ЛЕВАЯ КОЛОНКА -->
94
+ <q-drawer v-model="leftSideOpened" :breakpoint="700" :width="300" overlay class="col column shadow-5 bg-grey-1">
95
+ <div class="platform-ios-only q-py-lg" />
96
+ <div v-if="!$q.screen.gt.xs" class="q-pa-sm row items-center">
97
+ <q-icon name="account_circle" color="primary" size="32px" class="q-mr-sm" />
98
+ <div class="text-subtitle1">{{ user.name }}</div>
99
+ </div>
100
+ <n-menu v-model="activeMenu" :menu="menu" />
101
+ <q-space />
102
+ <n-menu :menu="homeMenu" />
103
+ <div class="platform-ios-only q-py-md" />
104
+ </q-drawer>
105
+
106
+ <q-page-container>
107
+ <router-view />
108
+ </q-page-container>
109
+ </q-layout>
110
+ </template>
111
+ <script setup>
112
+ import { lang, tf as tfm } from '@nitra/tfm'
113
+ const t = tfm.bind({ tr: getTr() })
114
+
115
+ const baseUrl = import.meta.env.BASE_URL
116
+ const homeUrl = String.raw`https:\\` + import.meta.env.VITE_DOMAIN
117
+
118
+ // Ліва колонка
119
+ const leftSideOpened = $ref(false)
120
+ const activeMenu = $ref(null)
121
+
122
+ // Заголовок у шапці з поточного пункту меню
123
+ const subtitle = computed(() => (activeMenu ? getTr()[activeMenu.labelKey]?.[lang.value] || activeMenu?.labelKey : ''))
124
+
125
+ // Меню
126
+ const menu = computed(() =>
127
+ [
128
+ {
129
+ icon: 'sym_o_store',
130
+ label: t`Клиенты`,
131
+ labelKey: t`Клиенты`,
132
+ routeName: 'customer'
133
+ },
134
+ {
135
+ icon: 'sym_o_route',
136
+ label: t`Маршруты и визиты`,
137
+ items: [
138
+ {
139
+ icon: 'sym_o_route',
140
+ label: t`Маршруты`,
141
+ labelKey: t`Маршруты`,
142
+ routeName: 'route'
143
+ },
144
+ {
145
+ icon: 'sym_o_event_upcoming',
146
+ label: t`Переносы маршрутов`,
147
+ labelKey: t`Переносы маршрутов`,
148
+ routeName: 'route_postpone'
149
+ }
150
+ ]
151
+ }
152
+ ].filter(item => {
153
+ if (item.items?.length) {
154
+ item.items = item.items.filter(i => can[i.permissionRoute || i.routeName])
155
+ return item.items.length > 0
156
+ }
157
+ return can[item.routeName]
158
+ })
159
+ )
160
+
161
+ /**
162
+ * LOCALIZATION
163
+ * @returns {object} translations
164
+ */
165
+ function getTr() {
166
+ return {
167
+ Клиенты: { en: 'Customers', ro: 'Clienți', tr: 'Müşteriler' }
168
+ }
169
+ }
170
+ </script>
171
+ ```
@@ -0,0 +1,25 @@
1
+ ## Заборонено імпортувати Node-нативні модулі у `.vue` SFC
2
+
3
+ Vue SFC виконується у браузері, тож API Node.js там недоступне. У `<script>` (включно з `<script setup>`)
4
+ заборонено будь-які імпорти вбудованих модулів Node — як з префіксом `node:`, так і bare-ім'ям модуля
5
+ (включно з підшляхами):
6
+
7
+ ```vue title="погано — ламає білд"
8
+ <script setup lang="ts">
9
+ import { setTimeout as sleep } from 'node:timers/promises'
10
+ import fs from 'fs'
11
+ import { readFile } from 'fs/promises'
12
+ import path from 'node:path'
13
+ </script>
14
+ ```
15
+
16
+ Якщо потрібна логіка з Node API — винеси її у server-side утіліту (наприклад, у backend-пакет монорепо)
17
+ та звертайся до неї через HTTP/GraphQL. Браузерні замінники (`window.crypto`, `URL`, `setTimeout` глобальний,
18
+ `AbortController` тощо) використовуй напряму, без import.
19
+
20
+ Правило стосується саме `.vue` файлів. Допоміжні `.ts`/`.js` модулі, які споживаються лише server-side
21
+ (наприклад, окремий пакет утіліт), можуть імпортувати Node-built-ins без обмежень.
22
+
23
+ Перевірка реалізована у `npm/rules/vue/lib/vue-forbidden-imports.mjs` через функцію
24
+ `findForbiddenNodeImportsInVueFile` — аналізує лише `<script>` блоки SFC через **oxc-parser**,
25
+ ігноруючи `<template>`.
@@ -0,0 +1,32 @@
1
+ ## Quasar як UI-основа
2
+
3
+ У Vue-проектах використовуй **Quasar** як базовий UI-фреймворк:
4
+
5
+ - **Компоненти:** `q-btn`, `q-input`, `q-select`, `q-table`, `q-dialog`, `q-card`, `q-layout`, `q-page`, `q-drawer` тощо — основа UI.
6
+ - **Плагіни:** `Notify`, `Dialog`, `Loading` та інші Quasar-плагіни.
7
+ - **Кольори:** використовуй Quasar CSS-змінні (`primary`, `secondary`, `accent`, `positive`, `negative`, `warning`, `info`, `dark`) і утиліти (`text-primary`, `bg-accent` тощо).
8
+ - **Утиліти:** flex-layout (`row`, `col`, `items-center`), spacing (`q-pa-md`, `q-mt-sm`), shadow (`shadow-2`) — зі стандартної бібліотеки Quasar.
9
+ - **Кастомні компоненти** `@nitra/components` — **надбудова** над Quasar, а не заміна; їх слід надавати перевагу лише там, де вони є.
10
+
11
+ ## @nitra/components — надавай перевагу перед Quasar-компонентами
12
+
13
+ При створенні нової функціональності використовуй компоненти `@nitra/components`, якщо логіка компонента дозволяє отримати потрібний функціонал. Заміни:
14
+
15
+ | Завдання | `@nitra/components` | Замість Quasar |
16
+ | --- | --- | --- |
17
+ | Діалоги | `NDialog` | `q-dialog` |
18
+ | Multi-вибір | `NSelectMulti` | `q-select` (multiple) |
19
+ | Текстовий редактор | `NEditor` | `q-editor` |
20
+ | Вибір дати | `NDate` | — |
21
+ | Вибір місяця/року | `NDateMonthYear` | — |
22
+ | Діапазон дат | `NDateRange` | — |
23
+ | Дата і час | `NDateTime` | — |
24
+ | Drag&drop список | `NDraggableList` | — |
25
+ | Редаговане значення | `NEditableString` | — |
26
+ | Повідомлення | `NCallout` | — |
27
+ | Хедер проекту | `NHeader` | — |
28
+ | Перемикання мов | `NLang` | — (якщо `NHeader` не використовується) |
29
+ | Меню проекту | `NMenu` | — |
30
+ | Зображення (масив / одиночне) | `NImages` | — |
31
+ | Завантаження файлів | `NUploader` | — |
32
+ | Вибір колонок `q-table` | `NTableColumns` | — |
@@ -0,0 +1,101 @@
1
+ ## Структура папок
2
+
3
+ ```javascript
4
+ const folderStructure = `
5
+ src/
6
+ components/
7
+ composables/
8
+ views/
9
+ router/
10
+ store/
11
+ assets/
12
+ public/
13
+ App.vue
14
+ main.mjs
15
+ `
16
+ ```
17
+
18
+ ### Найменування файлів
19
+
20
+ - **SFC:** імена файлів компонентів у **PascalCase** починаючи з букви N(`NMyWidget.vue`).
21
+ - **Інші JS-модулі:** узгоджено **kebab-case** (`date-utils.mjs`).
22
+
23
+ ### Модулі та архітектура
24
+
25
+ - **ES modules** (`import`/`export`), один модуль — одна відповідальність, уникай **circular dependencies**.
26
+ - **Composition** замість успадкування; логіку для повторного використання винось у **composables** (замість зайвих HOC, де це доречно).
27
+
28
+ ### Code splitting
29
+
30
+ - **Route-based:** lazy-імпорти в маршрутах (`() => import('...')`) і async components.
31
+
32
+ ## Додаткові вказівки
33
+
34
+ ```javascript
35
+ const additionalInstructions = `
36
+ 1. Використовуй JavaScript
37
+ 2. Коректно оголошуй props, emits, defineModel
38
+ 3. За потреби використовуй компонент Teleport у Vue 3
39
+ 4. Застосовуй Suspense для async components
40
+ 5. Реалізуй належний error handling
41
+ 6. Дотримуйся Vue 3 style guide і naming conventions
42
+ 7. Використовуй Vite для швидкої розробки та збірки
43
+ `
44
+ ```
45
+
46
+ ### Детальні вказівки
47
+
48
+ 1. **Vue router**: Завжди використовуй Vue router для маршрутизації в проекті версії 5 та його file-based routing.
49
+ 2. **Компонент Teleport**: Використовуй Teleport у Vue 3, коли потрібно рендерити поза поточною ієрархією DOM.
50
+ 3. **Suspense для async components**: Застосовуй Suspense для асинхронних компонентів і кращого UX.
51
+ 4. **Error handling**: Реалізуй глобальний error handling механізмами Vue 3, щоб коректно перехоплювати та обробляти помилки.
52
+ 5. **Style guide і naming**: Дотримуйся офіційного Vue 3 style guide і naming conventions для узгодженості кодової бази.
53
+ 6. **Vue macros**: Використовуй Vue macros для більш ефективного розробки компонентів.
54
+ 7. **Vue Reactivity Transform**: Використовуй Vue Reactivity Transform для змінних в компонентах.
55
+
56
+ ## Коментарі в `<template>`
57
+
58
+ Додавай коментарі в `<template>` відповідно до логічного призначення блоку. Коментарі допомагають швидко орієнтуватися в розмітці.
59
+
60
+ ```vue
61
+ <template>
62
+ <q-page>
63
+ <!-- ФІЛЬТРИ В ШАПЦІ -->
64
+ <teleport v-if="mounted" to="#header-filters">...</teleport>
65
+
66
+ <!-- ТАБЛИЦЯ -->
67
+ <q-table ... />
68
+
69
+ <!-- ДІАЛОГ РЕДАГУВАННЯ -->
70
+ <n-dialog v-model="editDialog">...</n-dialog>
71
+ </q-page>
72
+ </template>
73
+ ```
74
+
75
+ ## Pinia store для стану сторінки
76
+
77
+ Зберігай у Pinia store:
78
+
79
+ - вибрані значення фільтрів
80
+ - вибрані для відображення колонки (`NTableColumns`)
81
+ - кількість записів на сторінці (pagination)
82
+
83
+ Називай store за назвою сторінки або компонента — `customerPageStore`, `routePageStore` тощо. На сторінці звертайся до нього через змінну `pageStore`.
84
+
85
+ ```javascript
86
+ // store/customerPage.mjs
87
+ export const useCustomerPageStore = defineStore('customerPage', {
88
+ state: () => ({
89
+ filterName: '',
90
+ filterStatus: [],
91
+ columns: [],
92
+ rowsPerPage: 20
93
+ })
94
+ })
95
+ ```
96
+
97
+ ```vue
98
+ <script setup>
99
+ const pageStore = useCustomerPageStore()
100
+ </script>
101
+ ```
@@ -0,0 +1,32 @@
1
+ ## Тестування Vue-компонентів
2
+
3
+ ### Unit + Component / DOM
4
+
5
+ **Vitest** (`vitest`) + **Vue Test Utils** з **happy-dom** як DOM-середовищем. Це канон, узгоджений з `test.mdc` (Stryker з vitest-runner + `perTest`-аналіз покриття). `vitest.config.mjs` повторно використовує `vite.config.js` через `mergeConfig` і перемикає `environment` на `'happy-dom'`:
6
+
7
+ ```js title="vitest.config.mjs"
8
+ import { defineConfig, mergeConfig } from 'vitest/config'
9
+ import viteConfig from './vite.config.js'
10
+
11
+ export default mergeConfig(viteConfig, defineConfig({
12
+ test: {
13
+ include: ['**/*.test.{js,mjs}', 'tests/**/*.test.{js,mjs}'],
14
+ environment: 'happy-dom',
15
+ coverage: { provider: 'v8', reporter: ['lcov', 'text-summary'] }
16
+ }
17
+ }))
18
+ ```
19
+
20
+ `jsdom` не використовуй — happy-dom швидший і достатній для типових Vue-компонентних тестів.
21
+
22
+ У `package.json#scripts` тримай `"test": "vitest run"`; vitest devDeps (`vitest`, `@vitest/coverage-v8`, `@stryker-mutator/vitest-runner`) — у кореневому `devDependencies` (npm-module rule забороняє devDeps у published workspace-у).
23
+
24
+ ### E2E
25
+
26
+ **Playwright** — змістовні сценарії користувацьких потоків.
27
+
28
+ Проекту повинен бути покритий тестами E2E за допомогою Playwright.
29
+
30
+ ### CI/CD
31
+
32
+ У pipeline: **install**, **lint**, **test**, **vite build**; артефакти з продакшен-режиму.
@@ -0,0 +1,26 @@
1
+ ## @nitra/tfm — переклади
2
+
3
+ Використовуй `@nitra/tfm` для всіх текстів. Переклади для всіх мов проекту оголошуй наприкінці `<script setup>` у функції `getTr()`. Змінна `lang` із `@nitra/tfm` — для визначення або зміни поточної мови застосунку.
4
+
5
+ ```vue
6
+ <template>
7
+ {{ lang }}
8
+ {{ t`Анкеты` }}
9
+ {{ subtitle }}
10
+ </template>
11
+ <script setup>
12
+ import { lang, tf as tfm } from '@nitra/tfm'
13
+ const t = tfm.bind({ tr: getTr() })
14
+ const subtitle = $computed(() => t`Анкеты`)
15
+
16
+ /**
17
+ * LOCALIZATION
18
+ * @returns {object} translations
19
+ */
20
+ function getTr() {
21
+ return {
22
+ Анкеты: { en: 'Surveys', ro: 'Sondaje', tr: 'Anketler' }
23
+ }
24
+ }
25
+ </script>
26
+ ```
@@ -0,0 +1,126 @@
1
+ ## Vite-конфігурація: VueMacros, AutoImport, Layouts
2
+
3
+ Потрібно використовувати **Vite версії 8 та вище** для frontend проекту на Vue.
4
+
5
+ Потрібно використовувати **`unplugin-auto-import`** для автоматичного імпортування компонентів, composables, utils та інших функцій і прибирати з файлів усередині Vite проектів відповідні ручні імпорти, зокрема рядки виду `import { … } from 'vue'` — API Vue (`ref`, `computed`, `watch` тощо) мають підставлятися через auto-import, а не дублюватися явним імпортом з модуля `vue`.
6
+
7
+ **Виняток — бібліотеки компонентів (`vue` у `peerDependencies`).** Увесь стек auto-import застосовується лише коли `vue` підключено як звичайну `dependencies`. Якщо ж пакет оголошує `vue` у `peerDependencies` — це проєкт-бібліотека компонентів: його джерела споживаються Vite-додатками і **не** проходять через `unplugin-auto-import` споживача. Тому до таких пакетів **не** застосовуються: заборона явних `import { ref, computed, … } from 'vue'` (вони обовʼязкові), вимога `'vue'` у `AutoImport.imports`, а також вимоги наявності `VueMacros` / `AutoImport` у `vite.config`. Решта перевірок (заборона `esbuild`, `process.env.npm_lifecycle_event` тощо) лишаються. Тригер винятку — `isVueComponentLibraryPkg` у `npm/rules/vue/js/packages.mjs`.
8
+
9
+ Потрібно використовувати **`vite-plugin-vue-layouts-next`** для автоматичного імпортування layout компонентів.
10
+
11
+ ### Еталонний `vite.config.js`
12
+
13
+ ```javascript title="vite.config.js"
14
+ import Vue from '@vitejs/plugin-vue'
15
+ import VueMacros from 'vue-macros/vite'
16
+ import { defineConfig } from 'vite'
17
+ import AutoImport from 'unplugin-auto-import/vite'
18
+ import Layouts from 'vite-plugin-vue-layouts-next'
19
+
20
+ export default defineConfig({
21
+ plugins: [
22
+ AutoImport({
23
+ imports: [
24
+ // presets
25
+ 'vue',
26
+ 'vue-router',
27
+ 'quasar',
28
+ 'pinia',
29
+ // custom
30
+ {
31
+ '@nitra/vite-boot/apollo': [
32
+ // named imports
33
+ 'gql',
34
+ 'useQuery',
35
+ 'useMutation',
36
+ 'useSubscription'
37
+ ],
38
+ '@nitra/consola': [
39
+ // named imports
40
+ 'createLogger' // import { createLogger } from '@nitra/consola'
41
+ ]
42
+ }
43
+ ]
44
+ }),
45
+ VueMacros({
46
+ plugins: {
47
+ vue: Vue()
48
+ }
49
+ }),
50
+ Layouts()
51
+ ]
52
+ })
53
+ ```
54
+
55
+ ### Перевірка `npm_lifecycle_event` (Bun-сумісність)
56
+
57
+ У більшості проектів у файлі `vite.config.js` є конструкція виду:
58
+
59
+ ```javascript
60
+ switch (process.env.npm_lifecycle_event) {
61
+ case 'start-remote-tr': {
62
+ ```
63
+
64
+ Вона перестала працювати з новим Bun. Тепер її треба обрамити у функцію і передавати `mode`:
65
+
66
+ ```javascript title="vite.config.js"
67
+ function getProxy(mode) {
68
+ const proxy = {}
69
+
70
+ switch (mode) {
71
+ case 'remote-tr': {
72
+ proxy['^/auth/.*'] = 'https://tr.efes.cloud'
73
+ proxy['/file-link/'] = 'https://tr.efes.cloud'
74
+ break
75
+ }
76
+ default: {
77
+ proxy['^/auth/.*'] = 'https://dev.efes.cloud'
78
+ proxy['/file-link/'] = 'https://dev.efes.cloud'
79
+ }
80
+ }
81
+ return proxy
82
+ }
83
+ ```
84
+
85
+ ```javascript title="vite.config.js"
86
+ export default defineConfig(({ mode, command }) => {
87
+ // ...
88
+ server: {
89
+ proxy: getProxy(mode)
90
+ }
91
+ })
92
+ ```
93
+
94
+ ### esbuild заборонено
95
+
96
+ У проєкті не має бути залежності `esbuild` і згадок `esbuild` у конфігах/коді. Якщо десь є налаштування або інструкції під `esbuild` — заміни на **rolldown**.
97
+
98
+ ### Еталонний `package.json`
99
+
100
+ мінімальний повний `package.json` для Vite + Vue + `vue-macros` (версії підлаштуй під проєкт):
101
+
102
+ ```json title="package.json"
103
+ {
104
+ "name": "my-vue-app",
105
+ "private": true,
106
+ "type": "module",
107
+ "dependencies": {
108
+ "vue": "^3.6.12"
109
+ },
110
+ "devDependencies": {
111
+ "vite": "^8.0.0",
112
+ "@vitejs/plugin-vue": "^6.0.0",
113
+ "vue-macros": "^3.1.2"
114
+ }
115
+ }
116
+ ```
117
+
118
+ ### VS Code розширення
119
+
120
+ У файлі `.vscode/extensions.json` потрібна рекомендація для Vue:
121
+
122
+ ```json title=".vscode/extensions.json"
123
+ {
124
+ "recommendations": ["Vue.volar"]
125
+ }
126
+ ```
@@ -0,0 +1,55 @@
1
+ ## Vite client types (Volar, імпорти асетів)
2
+
3
+ Без типів **Vite** редактор (Volar / TypeScript) не знає, що імпорт статичного файлу (`import url from './hero.avif'`, `*.png`, `*.svg` тощо) відповідає модулю з `string` URL. Тоді у `.vue` з'являється помилка на кшталт **Cannot find module '…' or its corresponding type declarations**.
4
+
5
+ У **кожному** workspace-пакеті з **Vue + Vite** обов'язково:
6
+
7
+ 1. **`src/vite-env.d.ts`** — рівно з посиланням на клієнтські типи Vite (одного рядка достатньо):
8
+
9
+ ```ts title="src/vite-env.d.ts"
10
+ /// <reference types="vite/client" />
11
+ ```
12
+
13
+ Так підтягуються декларації з `vite/client.d.ts` (`declare module '*.avif'`, `*.png`, …).
14
+
15
+ 2. **Корінь пакета:** **`jsconfig.json`** із **`include`**, що охоплює `src` (наприклад `"include": ["src/**/*"]`), щоб мова служби бачила `vite-env.d.ts` і SFC.
16
+
17
+ Мінімальний приклад для JS-пакета:
18
+
19
+ ```json title="jsconfig.json"
20
+ {
21
+ "compilerOptions": {
22
+ "target": "ESNext",
23
+ "module": "ESNext",
24
+ "moduleResolution": "bundler",
25
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
26
+ "jsx": "preserve",
27
+ "strict": true,
28
+ "noEmit": true,
29
+ "skipLibCheck": true,
30
+ "resolveJsonModule": true,
31
+ "isolatedModules": true,
32
+ "allowJs": true
33
+ },
34
+ "include": ["src/**/*"]
35
+ }
36
+ ```
37
+
38
+ **Не** звужуй без потреби **`compilerOptions.types`** до `["vite/client"]`: це може відрізати інші пакети з `@types` і зламати інші підказки. Достатньо `/// <reference types="vite/client" />` у `vite-env.d.ts` і коректного `include`.
39
+
40
+ ## Статичні файли — BASE_URL
41
+
42
+ Для підключення статичних файлів не використовуй відносні шляхи. Завжди будуй URL через `import.meta.env.BASE_URL`:
43
+
44
+ ```vue
45
+ <!-- Погано -->
46
+ <img src="/logo.png" />
47
+ <img src="./assets/logo.png" />
48
+
49
+ <!-- Добре -->
50
+ <img :src="baseUrl + 'logo.png'" />
51
+ ```
52
+
53
+ ```javascript
54
+ const baseUrl = import.meta.env.BASE_URL
55
+ ```
@@ -0,0 +1,25 @@
1
+ ## Заборона явних value-імпортів з `vue`
2
+
3
+ Потрібно використовувати `unplugin-auto-import` для автоматичного імпортування Vue API. Коли `'vue'` додано до `AutoImport.imports` у `vite.config`, явні value-імпорти вигляду `import { ref, computed } from 'vue'` у файлах додатка **заборонені** — API Vue підставляється автоматично.
4
+
5
+ Дозволені лише:
6
+ - side-effect: `import 'vue'`
7
+ - type-only: `import type { … } from 'vue'` або `import { type Foo } from 'vue'`
8
+
9
+ ```vue
10
+ <!-- ❌ заборонено (auto-import покриває) -->
11
+ <script setup>
12
+ import { ref, computed, watch, onMounted } from 'vue'
13
+ </script>
14
+
15
+ <!-- ✅ дозволено — не потрібен ручний імпорт -->
16
+ <script setup>
17
+ const count = $ref(0)
18
+ const doubled = $computed(() => count * 2)
19
+ onMounted(() => { /* ... */ })
20
+ </script>
21
+ ```
22
+
23
+ **Виняток:** бібліотеки компонентів (`vue` у `peerDependencies`) — їхні джерела не проходять через `unplugin-auto-import` споживача, тому явні `import { ref } from 'vue'` там обовʼязкові. Визначається через `isVueComponentLibraryPkg` у `npm/rules/vue/js/packages.mjs`.
24
+
25
+ Перевірка виконується через **oxc-parser** (`module.staticImports`) у `npm/rules/vue/lib/vue-forbidden-imports.mjs`, функція `findForbiddenVueImportsInSourceFile`. Для `.vue` — лише вміст `<script>` тегів, `<template>` ігнорується.