@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
@@ -4,253 +4,42 @@ alwaysApply: true
4
4
  version: '1.30'
5
5
  ---
6
6
 
7
- **oxfmt** (`.oxfmtrc.json`, редактор), **cspell**, **shellcheck** (tracked `*.sh` у `lint-text`), **[dotenv-linter](https://dotenv-linter.github.io/)** (`.env*` у `lint-text`), **markdownlint-cli2**, **[v8r](https://chris48s.github.io/v8r/)** ([Schema Store](https://www.schemastore.org/)), розширення **DavidAnson.vscode-markdownlint** / **timonwong.shellcheck**, workflow **`lint-text`**.
7
+ Правило охоплює весь текстовий стек проєкту: форматування (oxfmt), перевірку правопису (cspell), shell-скрипти (shellcheck), `.env`-файли (dotenv-linter), Markdown (markdownlint-cli2), JSON/YAML/TOML-схеми (v8r) та CI-workflow.
8
8
 
9
- ```json title=".vscode/extensions.json"
10
- {
11
- "recommendations": [
12
- "dbaeumer.vscode-eslint",
13
- "github.vscode-github-actions",
14
- "oxc.oxc-vscode",
15
- "DavidAnson.vscode-markdownlint",
16
- "timonwong.shellcheck",
17
- "redhat.vscode-yaml",
18
- "irongeek.vscode-env"
19
- ]
20
- }
21
- ```
9
+ [text-vscode](./js/vscode.mdc)
22
10
 
23
- Канон `recommendations` (substring requirement): [extensions.json.snippet.json](./policy/vscode_extensions/template/extensions.json.snippet.json)
11
+ [text-oxfmt](./js/oxfmt.mdc)
24
12
 
25
- ```json title=".vscode/settings.json"
26
- {
27
- "files.associations": {
28
- "*.env.*": "env",
29
- "*.env": "env"
30
- },
31
- "editor.formatOnSave": true,
32
- "[css]": {
33
- "editor.defaultFormatter": "oxc.oxc-vscode"
34
- },
35
- "[graphql]": {
36
- "editor.defaultFormatter": "oxc.oxc-vscode"
37
- },
38
- "[handlebars]": {
39
- "editor.defaultFormatter": "oxc.oxc-vscode"
40
- },
41
- "[html]": {
42
- "editor.defaultFormatter": "oxc.oxc-vscode"
43
- },
44
- "[javascript]": {
45
- "editor.defaultFormatter": "oxc.oxc-vscode"
46
- },
47
- "[json]": {
48
- "editor.defaultFormatter": "oxc.oxc-vscode"
49
- },
50
- "[json5]": {
51
- "editor.defaultFormatter": "oxc.oxc-vscode"
52
- },
53
- "[jsonc]": {
54
- "editor.defaultFormatter": "oxc.oxc-vscode"
55
- },
56
- "[less]": {
57
- "editor.defaultFormatter": "oxc.oxc-vscode"
58
- },
59
- "[markdown]": {
60
- "editor.defaultFormatter": "oxc.oxc-vscode"
61
- },
62
- "[mdx]": {
63
- "editor.defaultFormatter": "oxc.oxc-vscode"
64
- },
65
- "[scss]": {
66
- "editor.defaultFormatter": "oxc.oxc-vscode"
67
- },
68
- "[toml]": {
69
- "editor.defaultFormatter": "oxc.oxc-vscode"
70
- },
71
- "[typescript]": {
72
- "editor.defaultFormatter": "oxc.oxc-vscode"
73
- },
74
- "[vue]": {
75
- "editor.defaultFormatter": "oxc.oxc-vscode"
76
- },
77
- "[yaml]": {
78
- "editor.defaultFormatter": "oxc.oxc-vscode"
79
- },
80
- "oxc.path.oxfmt": "/opt/homebrew/bin/oxfmt"
81
- }
82
- ```
13
+ [text-forbidden-prettier](./js/forbidden-prettier.mdc)
83
14
 
84
- Канон `editor.formatOnSave` + `editor.defaultFormatter` для основних мов: [settings.json.snippet.json](./policy/vscode_settings/template/settings.json.snippet.json)
15
+ [text-cspell](./js/cspell.mdc)
85
16
 
86
- У корені проєкту має бути файл з правилами форматування для **oxfmt**:
17
+ [text-markdownlint](./js/markdownlint.mdc)
87
18
 
88
- ```json title=".oxfmtrc.json"
89
- {
90
- "ignorePatterns": ["**/hasura/metadata/**", "**/schema.graphql", "**/auto-imports.d.ts"],
91
- "arrowParens": "avoid",
92
- "printWidth": 120,
93
- "bracketSpacing": true,
94
- "bracketSameLine": true,
95
- "embeddedLanguageFormatting": "auto",
96
- "endOfLine": "lf",
97
- "htmlWhitespaceSensitivity": "css",
98
- "insertPragma": false,
99
- "jsxSingleQuote": true,
100
- "proseWrap": "preserve",
101
- "quoteProps": "as-needed",
102
- "requirePragma": false,
103
- "semi": false,
104
- "singleQuote": true,
105
- "tabWidth": 2,
106
- "trailingComma": "none",
107
- "useTabs": false,
108
- "vueIndentScriptAndStyle": false
109
- }
110
- ```
19
+ [text-shellcheck](./js/shellcheck.mdc)
111
20
 
112
- Канон мінімального набору ключів і `ignorePatterns`: [.oxfmtrc.json.snippet.json](./policy/oxfmtrc/template/.oxfmtrc.json.snippet.json)
21
+ [text-dotenv-linter](./js/dotenv-linter.mdc)
113
22
 
114
- Поле **`ignorePatterns`** обовʼязкове: у масиві мають бути **`**/hasura/metadata/**`**, **`**/schema.graphql`** і **`**/auto-imports.d.ts`**; інші glob-и додавай за потреби (згенеровані каталоги тощо) — канон задає мінімум, локальні розширення дозволені.
23
+ [text-v8r](./js/v8r.mdc)
115
24
 
116
- Також потрібно прибрати, якщо є в проєкті, модуль **`@nitra/prettier-config`**, **prettier** та всі виклики prettier і налаштування для нього. Канон заборонених top-level/`dependencies`/`devDependencies` (prettier, `@nitra/prettier-config`, `markdownlint-cli2`): [package.json.deny.json](./policy/package_json/template/package.json.deny.json)
25
+ [text-package-json](./js/package-json.mdc)
117
26
 
118
- Завжди пиши **JSDoc** до функцій та методів.
27
+ [text-ci-lint-text](./js/ci-lint-text.mdc)
119
28
 
120
- **`package.json`:** у `devDependencies` має бути **`@nitra/cspell-dict`** (**`^2.0.0`** або новіший у лінії 2.x) — з **2.0.0** у пакет транзитивно входять типові **`@cspell/dict-*`**, тому **не** додавай їх окремо в корінь. Окремий `package.json`-скрипт `lint-text` не потрібен: запуск іде через **`n-cursor lint text`**. **`markdownlint-cli2`** запускається rule-адаптером через **`bunx markdownlint-cli2`**, не додавай пакет до devDependencies. **`v8r`** лише через **`bunx v8r`**, не в devDependencies. Окремий пакет **`markdownlint`** не потрібний.
29
+ ## Швидкий gate через conftest
121
30
 
122
- **shellcheck:** інструмент лише в **`PATH`** (як у **ga.mdc** для `lint-ga`), **не** додавай до `dependencies` / `devDependencies`. Якщо `shellcheck` відсутній — встанови локально (**macOS:** `brew install shellcheck`; **Debian/Ubuntu:** `sudo apt-get install -y shellcheck`; **Arch:** `sudo pacman -S shellcheck`). Канонічний запуск — **`n-cursor lint text`** (бінарка з `node_modules/.bin/` пакету `@nitra/cursor`): після **`cspell .`** виконується **`runShellcheckText()`** з пакета — циклічно **`shellcheck -f diff`** і **`patch -p1`** для авто-виправлень, потім повний прогін **`shellcheck`** по всіх tracked `*.sh` (у git) або по `**/*.sh` без `node_modules`. Потрібен також **`patch`** у `PATH` (на macOS зазвичай уже є).
31
+ Rego-пакети, що перевіряються через conftest (auto-discovered за `target.json` поряд із `.rego`):
123
32
 
124
- **dotenv-linter:** після shellcheck CLI запускає **`runDotenvLinter()`** з пакета — рекурсивно по `.env*`-файлах проєкту через **`dotenv-linter fix -r --no-backup --quiet . --exclude node_modules --exclude .envrc`**, далі такий самий **`check`** для фінальної перевірки. Інструмент має бути в **`PATH`** і **не** додається в `dependencies` / `devDependencies`. Якщо `dotenv-linter` відсутній — встанови локально (**macOS:** `brew install dotenv-linter`; **Linux:** `curl -sSfL https://git.io/JLbXn | sh -s -- -b /usr/local/bin`; через **cargo:** `cargo install dotenv-linter`).
33
+ [text-policy-cspell](./policy/cspell/cspell.mdc)
125
34
 
126
- У v8r **немає** прапорця тихого режиму; rule-адаптер **`n-cursor lint text`** на четвертому кроці викликає **`runV8rWithGlobs()`** з пакета (реалізація — `npm/rules/text/js/run-v8r.mjs`): під капотом послідовні **`bunx v8r`** для кожного типу (**json**, **json5**, **yml**, **yaml**, **toml**), бо один процес v8r з кількома глобами падає з **98**, якщо хоч один glob порожній, і тоді інші розширення не перевіряються. Вивід при кодах **0** і **98** не показується. Каталог схем **`schemas/v8r-catalog.json`** пакета `@nitra/cursor` обгортка підставляє в v8r сама.
35
+ [text-policy-lint_text](./policy/lint_text/lint_text.mdc)
127
36
 
128
- ```json title="package.json"
129
- {
130
- "devDependencies": {
131
- "@nitra/cspell-dict": "^2.1.0"
132
- }
133
- }
134
- ```
37
+ [text-policy-markdownlint](./policy/markdownlint/markdownlint.mdc)
135
38
 
136
- **v8r:** без обгортки — чотири виклики `(bunx v8r "<glob>" || [ $? -eq 98 ])` для **`**/*.json`**, **`**/*.yml`**, **`**/*.yaml`**, **`**/*.toml`** (за потреби окремо **json5**). Враховує `.gitignore`. Для **`**/*.json`** опційно додай **власний каталог схем** [`--catalogs`](https://chris48s.github.io/v8r/usage-examples/#using-a-custom-catlog) (наприклад `-c npm/schemas/v8r-catalog.json` у репозиторії пакета `@nitra/cursor` або `-c https://unpkg.com/@nitra/cursor/schemas/v8r-catalog.json`), щоб перевіряти **`.n-cursor.json`** за схемою з [unpkg](https://unpkg.com/@nitra/cursor/schemas/n-cursor.json).
39
+ [text-policy-oxfmtrc](./policy/oxfmtrc/oxfmtrc.mdc)
137
40
 
138
- У корені проєкту має бути **`.v8rignore`**: **v8r** шукає схему в [Schema Store](https://www.schemastore.org/); для JSON без запису там перевірка завершується помилкою. Мінімум виключи **`.vscode/extensions.json`** і **`.vscode/settings.json`** (немає стабільної схеми в каталозі). Інші файли без схеми — за тією ж логікою; не розширюй ignore, щоб приховати проблеми там, де схема є. За потреби додай **`.git/**`** (службові JSON під `.git`) та **`npm/schemas/n-cursor.json`** у репозиторії `@nitra/cursor`, якщо для цього файлу немає стабільної схеми в ланцюжку v8r.
41
+ [text-policy-package_json](./policy/package_json/package_json.mdc)
139
42
 
140
- ```text title=".v8rignore"
141
- .vscode/extensions.json
142
- .vscode/settings.json
143
- .git/**
144
- ```
43
+ [text-policy-vscode_extensions](./policy/vscode_extensions/vscode_extensions.mdc)
145
44
 
146
- ```json title=".markdownlint-cli2.jsonc"
147
- {
148
- "gitignore": true,
149
- "config": {
150
- "default": true,
151
- "MD013": false,
152
- "MD024": {
153
- "siblings_only": true
154
- },
155
- "MD029": false,
156
- "MD040": false,
157
- "MD041": false
158
- }
159
- }
160
- ```
161
-
162
- Канон: [.markdownlint-cli2.jsonc.snippet.jsonc](./policy/markdownlint/template/.markdownlint-cli2.jsonc.snippet.jsonc)
163
-
164
- **MD041** off навмисно (`.mdc` з frontmatter). Деталі — [markdownlint-cli2](https://github.com/DavidAnson/markdownlint-cli2).
165
-
166
- ## Cspell
167
-
168
- У корені проєкту має бути `.cspell.json` і залежності для cspell у кореневому `package.json` (зазвичай `devDependencies`).
169
-
170
- Додай workflow `.github/workflows/lint-text.yml`:
171
-
172
- - Канон: [lint-text.yml.snippet.yml](./policy/lint_text/template/lint-text.yml.snippet.yml)
173
-
174
- Перед **`./.github/actions/setup-bun-deps`** — **`actions/checkout@v6`** (див. **ga.mdc**). Після composite — кроки **`Install shellcheck`** (apt) і **`Install dotenv-linter`** (curl), бо `n-cursor lint text` вимагає обидва бінарники в PATH; на ubuntu-latest shellcheck часто вже є, dotenv-linter — ні. Composite: Node 24, Bun, кеш, `bun install --frozen-lockfile`.
175
-
176
- Не дублюй окремий workflow з тими самими кроками cspell/markdownlint.
177
-
178
- **`.cspell.json`**, `version: "0.2"`, **`language`**, **`import`** з `@nitra/cspell-dict`, **`ignorePaths`**, **`words`** лише для назв/термінів, коли не виправити текстом.
179
-
180
- Базово (англійська + українська + корпоративний словник):
181
-
182
- ```json title=".cspell.json"
183
- {
184
- "version": "0.2",
185
- "language": "nitra",
186
- "ignorePaths": ["**/node_modules/**", "**/vscode-extension/**", "**/.git/**", ".vscode", "report", "*.svg", "**/k8s/**/*.yaml", "docs/adr/**"],
187
- "import": ["@nitra/cspell-dict/cspell-ext.json"],
188
- "words": []
189
- }
190
- ```
191
-
192
- Канон базових ключів `.cspell.json` (`version`, `ignorePaths`): [.cspell.json.snippet.json](./policy/cspell/template/.cspell.json.snippet.json). Обовʼязковий запис у `import`: [.cspell.json.contains.json](./policy/cspell/template/.cspell.json.contains.json). Заборонено імпортувати окремі `@cspell/dict-*` у `.cspell.json`: [.cspell.json.deny.json](./policy/cspell/template/.cspell.json.deny.json).
193
-
194
- `docs/adr/**` у канонічному `ignorePaths` — машинно-генеровані MADR-документи (драфти `capture-decisions.sh` + clean-ADR-и після `normalize-decisions.sh`). cspell-перевірка там безглузда: чернетка стирається наступним прогоном хук-ланцюжка, а будь-яка ручна правка правопису перезаписується. Локальні розширення `ignorePaths` дозволені — це лише мінімум.
195
-
196
- ```json title="package.json"
197
- {
198
- "devDependencies": {
199
- "@nitra/cspell-dict": "^2.1.0"
200
- }
201
- }
202
- ```
203
-
204
- ## Проєкт з українською та російською (і суміжні мови)
205
-
206
- У **`@nitra/cspell-dict`** від **2.0.0** уже зібрані залежності на **`@cspell/dict-uk-ua`**, **`@cspell/dict-ru_ru`** та інші типові словники — **не** дублюй їх у кореневому `package.json` і **не** імпортуй **`@cspell/dict-*/cspell-ext.json`** у `.cspell.json`.
207
-
208
- **1. Залежності** — лише корпоративний пакет:
209
-
210
- ```json title="package.json"
211
- {
212
- "devDependencies": {
213
- "@nitra/cspell-dict": "^2.1.0"
214
- }
215
- }
216
- ```
217
-
218
- Встановлення: `bun add -d @nitra/cspell-dict@^2.0.0`.
219
-
220
- **2. `.cspell.json`** — у полі **`language`** додай потрібні коди (наприклад **`uk`**, **`ru-ru`** разом з **`en`** та **`nitra`**). У **`import`** залиш лише **`@nitra/cspell-dict/cspell-ext.json`**:
221
-
222
- ```json title=".cspell.json"
223
- {
224
- "version": "0.2",
225
- "language": "en,uk,ru-ru,nitra",
226
- "ignorePaths": ["**/node_modules/**", "**/vscode-extension/**", "**/.git/**", ".vscode", "report", "*.svg", "**/k8s/**/*.yaml", "docs/adr/**"],
227
- "import": ["@nitra/cspell-dict/cspell-ext.json"],
228
- "words": []
229
- }
230
- ```
231
-
232
- Підлаштуй **`language`** під проєкт. Порядок у **`import`** може впливати на пріоритет словників — тримай корпоративний **`@nitra/cspell-dict`** першим, якщо додаєш інші розширення (рідко).
233
-
234
- **Український апостроф:** у словах не використовуй прямий символ `'` (U+0027); потрібен типографський апостроф `’` (U+2019). Якщо після цього cspell досі підсвічує слово як невідоме — додай його до масиву `words` у `.cspell.json`.
235
-
236
- ## Локальні виключення (cspell `words`)
237
-
238
- Коли **cspell** підсвічує слово, спочатку **виправ текст**, а не розширюй словник:
239
-
240
- - виправ **друкарські помилки** та неправильні форми;
241
- - **перефразуй коректною українською** (або англійською, залежно від контексту файлу): заміни кальки й випадкові склади на звичні формулювання зі словників;
242
- - заміни **жаргон**, якщо є природний еквівалент у тому ж стилі документації (наприклад, у коментарях пиши «функція зворотного виклику» замість розмовного запозичення з англійського `callback`).
243
-
244
- У секцію `words` у `.cspell.json` додавай записи **лише якщо переписати коректно неможливо** або **недоречно**: власні назви, стабільні технічні терміни без усталеного перекладу в проєкті, ідентифікатори зовнішніх API тощо.
245
-
246
- ## Інші мови
247
-
248
- Якщо потрібна мова вже є в залежностях **`@nitra/cspell-dict`** — додай лише код у **`language`**, без окремих **`@cspell/dict-*`** у споживачі. Якщо мови немає в корпоративному пакеті — розширюй **`@nitra/cspell-dict`**, а не підключай **`@cspell/dict-*`** у корені репозиторію-споживача. Огляд upstream-словників: [streetsidesoftware/cspell-dicts](https://github.com/streetsidesoftware/cspell-dicts).
249
-
250
- ## Найменування каталогів
251
-
252
- kebab-case
253
-
254
- ## Перевірка
255
-
256
- `npx @nitra/cursor fix text` (охоплює oxfmt, cspell, shellcheck, markdownlint, v8r і CI для `n-cursor lint text`). Зокрема падає, якщо у корені є `.prettierignore`, `.prettierrc*`, `prettier.config.*` або у `package.json#scripts` зустрічається команда з `prettier` — Prettier повністю заборонено, форматування лише через **oxfmt**.
45
+ [text-policy-vscode_settings](./policy/vscode_settings/vscode_settings.mdc)
@@ -0,0 +1,34 @@
1
+ ## Перевірка `.cspell.json` — структура та canonical import
2
+
3
+ Rego-пакет: `text.cspell`
4
+
5
+ Цільовий файл: `.cspell.json`
6
+
7
+ **Що перевіряється:**
8
+
9
+ - `version` — має відповідати канону (наразі `"0.2"`)
10
+ - `language` — поле обов'язкове (presence-only, значення довільне, наприклад `"en,uk"`)
11
+ - `ignorePaths` — масив має бути надмножиною канонічних glob-ів, включно з `docs/adr/**`
12
+ - `import` — має містити підрядок `@nitra/cspell-dict`; заборонені будь-які записи з підрядком `@cspell/dict-` (використовуй лише `@nitra/cspell-dict`)
13
+
14
+ **Приклади:**
15
+
16
+ ✓ правильно:
17
+ ```json
18
+ {
19
+ "version": "0.2",
20
+ "language": "en,uk",
21
+ "import": ["@nitra/cspell-dict/cspell-ext.json"],
22
+ "ignorePaths": ["**/node_modules/**", "**/.git/**", "docs/adr/**"]
23
+ }
24
+ ```
25
+
26
+ ✗ неправильно:
27
+ ```json
28
+ {
29
+ "version": "0.1",
30
+ "import": ["@cspell/dict-de"],
31
+ "ignorePaths": []
32
+ }
33
+ ```
34
+ (відсутнє `language`, застарілий `version`, заборонений `@cspell/dict-`, не всі canonical `ignorePaths`)
@@ -0,0 +1,19 @@
1
+ ## Перевірка `.github/workflows/lint-text.yml` — структура CI-workflow
2
+
3
+ Rego-пакет: `text.lint_text`
4
+
5
+ Цільовий файл: `.github/workflows/lint-text.yml`
6
+
7
+ **Що перевіряється:**
8
+
9
+ - `name` — має бути `"Lint Text"`
10
+ - `on.push.branches` та `on.pull_request.branches` — мають містити `dev` і `main`
11
+ - `on.push.paths` — має бути надмножиною канонічних glob-ів (усі текстові розширення)
12
+ - `jobs.text` — job обов'язковий
13
+ - `jobs.text.runs-on` — має бути `ubuntu-latest`
14
+ - `jobs.text.permissions.contents` — має бути `read`
15
+ - `jobs.text.steps` — не порожній; має містити всі канонічні `uses:` та `run:` підрядки
16
+
17
+ Канонічна структура workflow: [lint-text.yml.snippet.yml](./template/lint-text.yml.snippet.yml)
18
+
19
+ **Примітка:** conftest парсить YAML 1.1, де ключ `on:` без лапок перетворюється на булевий `true` — rego читає on-блок через `input["true"]`.
@@ -0,0 +1,38 @@
1
+ ## Перевірка `.markdownlint-cli2.jsonc` — конфігурація markdownlint
2
+
3
+ Rego-пакет: `text.markdownlint`
4
+
5
+ Цільовий файл: `.markdownlint-cli2.jsonc`
6
+
7
+ **Що перевіряється (generic walker по канонічному snippet):**
8
+
9
+ - Top-level scalar leafs (наприклад `gitignore: true`)
10
+ - 2-рівневі leafs: `config.<rule>` — скалярні значення правил (MD013, MD029, MD040, MD041 тощо)
11
+ - 3-рівневі leafs: `config.MD024.siblings_only` — вкладене поле
12
+ - Наявність самого об'єкта `config` (якщо відсутній — deny)
13
+
14
+ **Приклади:**
15
+
16
+ ✓ правильно:
17
+ ```jsonc
18
+ {
19
+ "gitignore": true,
20
+ "config": {
21
+ "MD013": false,
22
+ "MD024": { "siblings_only": true },
23
+ "MD029": false,
24
+ "MD040": false,
25
+ "MD041": false
26
+ }
27
+ }
28
+ ```
29
+
30
+ ✗ неправильно:
31
+ ```jsonc
32
+ {
33
+ "gitignore": false,
34
+ "config": {
35
+ "MD024": {}
36
+ }
37
+ }
38
+ ```
@@ -0,0 +1,11 @@
1
+ ## Перевірка `.oxfmtrc.json` — конфігурація oxfmt форматера
2
+
3
+ Rego-пакет: `text.oxfmtrc`
4
+
5
+ Цільовий файл: `.oxfmtrc.json`
6
+
7
+ **Що перевіряється:**
8
+
9
+ - Наявність усіх обов'язкових ключів (presence-only): `arrowParens`, `printWidth`, `bracketSpacing`, `bracketSameLine`, `semi`, `singleQuote`, `tabWidth`, `trailingComma`, `useTabs`
10
+ - Scalar leafs: точні значення відповідно до канонічного snippet
11
+ - `ignorePatterns`: масив має бути надмножиною канонічних glob-ів (subset-of перевірка)
@@ -0,0 +1,33 @@
1
+ ## Перевірка `package.json` — текст-специфічні обмеження
2
+
3
+ Rego-пакет: `text.package_json`
4
+
5
+ Цільовий файл: `package.json`
6
+
7
+ **Що перевіряється:**
8
+
9
+ - Заборонені top-level поля: `prettier`
10
+ - Заборонені пакети у `dependencies` / `devDependencies`: `prettier`, `@nitra/prettier-config`, `markdownlint-cli2` (використовуй `bunx` у lint-text)
11
+ - `@nitra/cspell-dict` обов'язковий у `devDependencies` з версією `^2.0.0` або новішою
12
+ - `scripts.*` — будь-який скрипт, що викликає `prettier` (через `bunx`, `npx`, прямо або через шлях), заборонений; використовуй `oxfmt`
13
+
14
+ Список заборонених пакетів: [package.json.deny.json](./template/package.json.deny.json)
15
+
16
+ **Приклади:**
17
+
18
+ ✓ правильно:
19
+ ```json
20
+ {
21
+ "devDependencies": { "@nitra/cspell-dict": "^2.0.0" },
22
+ "scripts": { "format": "oxfmt --write ." }
23
+ }
24
+ ```
25
+
26
+ ✗ неправильно:
27
+ ```json
28
+ {
29
+ "prettier": "@nitra/prettier-config",
30
+ "devDependencies": { "prettier": "^3.0.0", "@nitra/cspell-dict": "^1.0.0" },
31
+ "scripts": { "fix": "bunx prettier --write ." }
32
+ }
33
+ ```
@@ -0,0 +1,13 @@
1
+ ## Перевірка `.vscode/extensions.json` — канонічні розширення
2
+
3
+ Rego-пакет: `text.vscode_extensions`
4
+
5
+ Цільовий файл: `.vscode/extensions.json`
6
+
7
+ **Що перевіряється:**
8
+
9
+ - `recommendations` має бути надмножиною канонічного списку розширень
10
+
11
+ Канонічний snippet: [extensions.json.snippet.json](./template/extensions.json.snippet.json)
12
+
13
+ Обов'язкові розширення: `DavidAnson.vscode-markdownlint`, `oxc.oxc-vscode`, `timonwong.shellcheck`
@@ -0,0 +1,13 @@
1
+ ## Перевірка `.vscode/settings.json` — налаштування редактора
2
+
3
+ Rego-пакет: `text.vscode_settings`
4
+
5
+ Цільовий файл: `.vscode/settings.json`
6
+
7
+ **Що перевіряється (generic walker по канонічному snippet):**
8
+
9
+ - Scalar leafs: `editor.formatOnSave` має бути `true`
10
+ - Об'єктні блоки мовних налаштувань `[javascript]`, `[typescript]`, `[json]`, `[vue]`, `[css]`, `[html]`: `editor.defaultFormatter` має бути `"oxc.oxc-vscode"`
11
+ - Якщо блок відсутній або не є об'єктом — deny
12
+
13
+ Канонічний snippet: [settings.json.snippet.json](./template/settings.json.snippet.json)
@@ -0,0 +1,82 @@
1
+ ## Найкращі практики Vue 3 Composition API
2
+
3
+ ```javascript
4
+ const vue3CompositionApiBestPractices = [
5
+ 'Використовуй функцію setup() для логіки компонента',
6
+ 'Реалізуй computed змінні через $computed()',
7
+ 'Реалізуй ref змінні через $ref',
8
+ 'Використовуй watch і watchEffect для побічних ефектів',
9
+ 'Підключай lifecycle hooks: onMounted, onUpdated тощо',
10
+ 'Для глибоко вкладених залежностей використовуй composables, props/emits або store'
11
+ 'не використовуй provide/inject для залежностей'
12
+ ]
13
+ ```
14
+
15
+ ### Патерни та антипатерни
16
+
17
+ - Для глибоко вкладених залежностей використовуй **composables**, **props/emits** або **store**; **renderless**-компоненти / **slots** — коли логіку відділяєш від розмітки.
18
+ - **HTTP:** окремі модулі **services** або **composables** для API; **async/await**.
19
+ - **Події:** батько–дитина через **emits**; для не пов'язаних гілок — **store**.
20
+ - Не мутуй **props** напряму — оновлення через подію вгору або v-model.
21
+ - Обмежуй зайве в глобальному стані; локальний стан у компоненті — за замовчуванням.
22
+ - Уникай прямої роботи з **DOM**, якщо достатньо реактивного шаблону та ref.
23
+
24
+ ### State management
25
+
26
+ - **Single source of truth** для спільних даних: у нових проєктах на Vue 3 **Pinia** (модульні stores, actions).
27
+ - Похідний стан — через обчислення в store або **computed** у компонентах, без «тихих» побічних ефектів у getters.
28
+
29
+ ### Обробка помилок
30
+
31
+ - **try/catch** навколо async-операцій; зрозумілі повідомлення для користувача через notifySuccess, notifyError; логування на сервіс моніторингу за потреби.
32
+
33
+ ### Продуктивність
34
+
35
+ - **v-for** — стабільні унікальні **`:key`**; не плутай **v-if** (умовний mount) і **v-show** (перемикання visibility).
36
+ - **debounce/throttle** для частих подій.
37
+ - Після ручних **addEventListener** / підписок — прибирай у **onUnmounted**.
38
+
39
+ ### Функції в шаблоні
40
+
41
+ Виклики функцій у шаблоні дозволені **лише** в обробниках подій (`@click`, `@change` тощо). У всіх інших місцях — `v-if`, `v-show`, атрибутах (`:prop`), інтерполяціях (`{{ }}`) — замінюй функції на `computed`-властивості: функція виконується при **кожному** render-і, тоді як `computed` кешується і перераховується лише при зміні залежностей.
42
+
43
+ ```vue
44
+ <!-- ❌ функція в умові, атрибуті та інтерполяції -->
45
+ <q-item v-if="getItems(order).length" :label="getLabel(item)">
46
+ {{ formatName(user) }}
47
+ </q-item>
48
+
49
+ <!-- ✅ реактивні змінні / computed / props -->
50
+ <q-item v-if="itemsMap[order.id].length" :label="item.label">
51
+ {{ user.displayName }}
52
+ </q-item>
53
+ <!-- обробник події — виклик функції дозволений -->
54
+ <q-btn @click="doSomething(item)" />
55
+ ```
56
+
57
+ ### Безпека
58
+
59
+ - Не довіряй **v-html** без санітизації; для форм/API — **CSRF**-захист за потреби; валідація **на сервері** обов'язкова.
60
+
61
+ ### Приклад компонента
62
+
63
+ ```javascript
64
+ // Приклад Vue 3 компонента з Composition API
65
+ import { computed, onMounted } from 'vue'
66
+
67
+ export default {
68
+ setup() {
69
+ const count = $ref(0)
70
+ const doubleCount = $computed(() => count * 2)
71
+
72
+ onMounted(() => {
73
+ console.log('Компонент змонтовано')
74
+ })
75
+
76
+ return {
77
+ count,
78
+ doubleCount
79
+ }
80
+ }
81
+ }
82
+ ```