@7n/rules 1.7.0 → 1.7.2

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 (111) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +1 -1
  3. package/rules/abie/http_route_base/http_route_base.mdc +23 -1
  4. package/rules/adr/madr_format/concern.json +1 -0
  5. package/rules/adr/madr_format/madr_format.mdc +119 -0
  6. package/rules/bun/bunfig/bunfig.mdc +5 -0
  7. package/rules/bun/lint-surface/concern.json +3 -0
  8. package/rules/bun/lint-surface/lint-surface.mdc +13 -0
  9. package/rules/capacitor/platforms/docs/main.md +1 -1
  10. package/rules/capacitor/platforms/main.mjs +5 -1
  11. package/rules/capacitor/platforms/platforms.mdc +108 -0
  12. package/rules/changelog/consistency/comparison-models.mdc +46 -0
  13. package/rules/changelog/consistency/consistency.mdc +35 -0
  14. package/rules/docker/main.mdc +235 -2
  15. package/rules/image-avif/avif_generation/avif_generation.mdc +14 -0
  16. package/rules/js/check/check.mdc +26 -0
  17. package/rules/js/file-extensions/concern.json +3 -0
  18. package/rules/js/file-extensions/file-extensions.mdc +12 -0
  19. package/rules/js/jscpd_config/jscpd_config.mdc +28 -0
  20. package/rules/js/knip/knip.mdc +15 -0
  21. package/rules/js/utils_imports/utils_imports.mdc +15 -0
  22. package/rules/js-bun-db/connection/concern.json +3 -0
  23. package/rules/js-bun-db/connection/connection.mdc +42 -0
  24. package/rules/js-bun-db/package_json/package_json.mdc +15 -1
  25. package/rules/js-bun-db/pg_format_identifiers/concern.json +3 -0
  26. package/rules/js-bun-db/pg_format_identifiers/pg_format_identifiers.mdc +104 -0
  27. package/rules/js-bun-db/safety/safety.mdc +458 -0
  28. package/rules/js-mssql/main.mdc +130 -0
  29. package/rules/js-mssql/mssql-tvp/concern.json +3 -0
  30. package/rules/js-mssql/mssql-tvp/mssql-tvp.mdc +77 -0
  31. package/rules/js-run/configmap/configmap.mdc +6 -0
  32. package/rules/js-run/jsconfig/jsconfig.mdc +23 -0
  33. package/rules/js-run/package_json/package_json.mdc +6 -0
  34. package/rules/js-run/project-structure/concern.json +3 -0
  35. package/rules/js-run/project-structure/project-structure.mdc +11 -0
  36. package/rules/js-run/runtime/runtime.mdc +170 -0
  37. package/rules/js-run/scope/concern.json +3 -0
  38. package/rules/js-run/scope/scope.mdc +11 -0
  39. package/rules/k8s/hasura_configmap/hasura_configmap.mdc +6 -0
  40. package/rules/k8s/hpa_pdb/hpa_pdb.mdc +134 -0
  41. package/rules/k8s/kubeconform/kubeconform.mdc +38 -0
  42. package/rules/k8s/kustomization/kustomization.mdc +73 -0
  43. package/rules/k8s/main.mdc +68 -0
  44. package/rules/k8s/manifest/manifest.mdc +37 -0
  45. package/rules/k8s/manifests/docs/fix-manifests.md +3 -1
  46. package/rules/k8s/manifests/fix-manifests.mjs +11 -0
  47. package/rules/k8s/manifests/main.mjs +28 -0
  48. package/rules/k8s/network_policy/network_policy.mdc +33 -0
  49. package/rules/nginx-default-tpl/http-route/concern.json +1 -0
  50. package/rules/nginx-default-tpl/http-route/http-route.mdc +54 -0
  51. package/rules/nginx-default-tpl/template/template.mdc +152 -0
  52. package/rules/php/tooling/tooling.mdc +7 -6
  53. package/rules/python/pyproject_toml/pyproject_toml.mdc +17 -1
  54. package/rules/python/tooling/tooling.mdc +9 -10
  55. package/rules/rego/main.mdc +14 -0
  56. package/rules/rust/check/check.mdc +16 -0
  57. package/rules/style/admin_table/admin_table.mdc +88 -0
  58. package/rules/style/admin_table/concern.json +7 -0
  59. package/rules/style/admin_table/docs/index.md +9 -0
  60. package/rules/style/admin_table/docs/main.md +14 -0
  61. package/rules/style/admin_table/main.mjs +46 -0
  62. package/rules/style/colors/colors.mdc +21 -0
  63. package/rules/style/colors/concern.json +3 -0
  64. package/rules/style/gap/concern.json +7 -0
  65. package/rules/style/gap/docs/index.md +9 -0
  66. package/rules/style/gap/docs/main.md +15 -0
  67. package/rules/style/gap/gap.mdc +22 -0
  68. package/rules/style/gap/main.mjs +51 -0
  69. package/rules/style/quasar/concern.json +3 -0
  70. package/rules/style/quasar/quasar.mdc +7 -0
  71. package/rules/style/quasar_fixes/concern.json +7 -0
  72. package/rules/style/quasar_fixes/docs/index.md +9 -0
  73. package/rules/style/quasar_fixes/docs/main.md +16 -0
  74. package/rules/style/quasar_fixes/main.mjs +57 -0
  75. package/rules/style/quasar_fixes/quasar_fixes.mdc +32 -0
  76. package/rules/tauri/release/release.mdc +5 -2
  77. package/rules/tauri/tool_surface/concern.json +16 -0
  78. package/rules/tauri/tool_surface/docs/index.md +9 -0
  79. package/rules/tauri/tool_surface/docs/main.md +24 -0
  80. package/rules/tauri/tool_surface/main.mjs +145 -0
  81. package/rules/tauri/tool_surface/tool_surface.mdc +29 -0
  82. package/rules/test/vitest-api-conventions/concern.json +7 -0
  83. package/rules/test/vitest-api-conventions/docs/index.md +9 -0
  84. package/rules/test/vitest-api-conventions/docs/main.md +40 -0
  85. package/rules/test/vitest-api-conventions/main.mjs +186 -0
  86. package/rules/test/vitest-api-conventions/vitest-api-conventions.mdc +129 -0
  87. package/rules/text/cspell/cspell.mdc +18 -0
  88. package/rules/text/markdownlint/markdownlint.mdc +4 -0
  89. package/rules/text/run-dotenv-linter/run-dotenv-linter.mdc +17 -0
  90. package/rules/text/run-shellcheck/run-shellcheck.mdc +17 -0
  91. package/rules/text/run-v8r/run-v8r.mdc +23 -0
  92. package/rules/vue/composition-api/composition-api.mdc +82 -0
  93. package/rules/vue/composition-api/concern.json +3 -0
  94. package/rules/vue/main.mdc +1 -1
  95. package/rules/vue/nheader-layout/concern.json +3 -0
  96. package/rules/vue/nheader-layout/nheader-layout.mdc +171 -0
  97. package/rules/vue/packages/packages.mdc +56 -0
  98. package/rules/vue/quasar-ui/concern.json +3 -0
  99. package/rules/vue/quasar-ui/quasar-ui.mdc +32 -0
  100. package/rules/vue/structure/concern.json +3 -0
  101. package/rules/vue/structure/structure.mdc +101 -0
  102. package/rules/vue/testing/concern.json +3 -0
  103. package/rules/vue/testing/testing.mdc +40 -0
  104. package/rules/vue/tfm-translations/concern.json +7 -0
  105. package/rules/vue/tfm-translations/docs/main.md +29 -0
  106. package/rules/vue/tfm-translations/main.mjs +55 -0
  107. package/rules/vue/tfm-translations/tfm-translations.mdc +32 -0
  108. package/rules/vue/vite-config/concern.json +3 -0
  109. package/rules/vue/vite-config/vite-config.mdc +153 -0
  110. package/rules/vue/vite-env/concern.json +3 -0
  111. package/rules/vue/vite-env/vite-env.mdc +61 -0
@@ -0,0 +1,88 @@
1
+ ## Адмінські таблиці — n-admin-table
2
+
3
+ Для таблиць, що мають займати всю висоту сторінки (або блоку), додавай клас `n-admin-table` і атрибути `hide-no-data`, `dense`, `flat`. Таблиця автоматично розтягнеться на весь доступний простір. У блоках меншої висоти — задай їм явний `height`.
4
+
5
+ ```vue
6
+ <!-- ТАБЛИЦЯ -->
7
+ <q-table class="n-admin-table" hide-no-data flat dense />
8
+ ```
9
+
10
+ Якщо клас `.n-admin-table` не визначено в `app.scss` — додай:
11
+
12
+ ```scss
13
+ // ADMIN TABLE
14
+ .n-admin-table {
15
+ height: calc(100vh - 106px);
16
+
17
+ thead {
18
+ position: sticky;
19
+ z-index: 3;
20
+ top: 0;
21
+
22
+ tr th {
23
+ background-color: $grey-3;
24
+ height: 36px !important;
25
+ }
26
+ }
27
+
28
+ // tbody td {
29
+ // font-size: 14px;
30
+ // }
31
+
32
+ tbody tr:last-child td {
33
+ border-bottom: 1px solid rgb(0 0 0 / 12%) !important;
34
+ }
35
+
36
+ th:first-child,
37
+ td:first-child,
38
+ th:last-child,
39
+ td:last-child {
40
+ width: 1px;
41
+ white-space: nowrap;
42
+ }
43
+
44
+ .q-table__bottom {
45
+ background-color: $grey-3;
46
+ }
47
+
48
+ .q-table__progress th {
49
+ height: 1px !important;
50
+ }
51
+
52
+ .text-wrap {
53
+ max-width: 250px;
54
+ white-space: normal;
55
+ }
56
+
57
+ // sticky columns
58
+ td.sticky-left {
59
+ position: sticky;
60
+ left: 0;
61
+ z-index: 2;
62
+ background-color: white;
63
+ box-shadow: 2px 0 5px #0002;
64
+ }
65
+
66
+ td.sticky-right {
67
+ position: sticky;
68
+ right: 0;
69
+ z-index: 2;
70
+ background-color: white;
71
+ box-shadow: -2px 0 5px #0002;
72
+ }
73
+
74
+ th.sticky-left {
75
+ position: sticky;
76
+ left: 0;
77
+ z-index: 3;
78
+ box-shadow: 2px 0 5px #0002;
79
+ }
80
+
81
+ th.sticky-right {
82
+ position: sticky;
83
+ right: 0;
84
+ z-index: 3;
85
+ box-shadow: -2px 0 5px #0002;
86
+ }
87
+ }
88
+ ```
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json",
3
+ "lint": {
4
+ "scope": "full",
5
+ "glob": ["**/*.vue", "**/*.scss", "**/*.css"]
6
+ }
7
+ }
@@ -0,0 +1,9 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/style/admin_table
4
+ resource: npm/rules/style/admin_table/
5
+ ---
6
+
7
+ | Файл | Тип |
8
+ | ------------------- | --------- |
9
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,14 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/style/admin_table/main.mjs
5
+ docgen:
6
+ crc: 9e484318
7
+ ---
8
+
9
+ ## Огляд
10
+
11
+ Детектор concern-а `admin_table` (read-only, whole-repo): якщо десь у `.vue`-файлі
12
+ використано клас `n-admin-table`, він має бути визначений хоч в одному `.scss`/`.css`/`.vue`
13
+ файлі проєкту, інакше — порушення `missing-admin-table-style`. Потребує whole-repo
14
+ сканування (usage і definition можуть бути в різних файлах), тому не залежить від `ctx.files`.
@@ -0,0 +1,46 @@
1
+ /** @see ./docs/main.md */
2
+ import { readFile } from 'node:fs/promises'
3
+
4
+ import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
5
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
6
+
7
+ const RELEVANT_RE = /\.(?:vue|scss|css)$/u
8
+ const USAGE_RE = /\bn-admin-table\b/u
9
+ const DEFINITION_RE = /\.n-admin-table\b/u
10
+
11
+ /**
12
+ * Detector style/admin_table (read-only, whole-repo): якщо десь у `.vue` використано
13
+ * клас `n-admin-table`, він має бути визначений хоч в одному `.scss`/`.css`/`.vue`
14
+ * (guide: `admin_table.mdc`). Для усунення false positives — крос-файлова перевірка,
15
+ * тож потребує whole-repo сканування незалежно від `ctx.files`.
16
+ * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
17
+ * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
18
+ */
19
+ export async function lint(ctx) {
20
+ const reporter = createViolationReporter(ctx)
21
+ const { fail } = reporter
22
+ const cwd = ctx.cwd
23
+
24
+ /** @type {string[]} */
25
+ const files = []
26
+ await walkDir(cwd, f => {
27
+ if (RELEVANT_RE.test(f)) files.push(f)
28
+ })
29
+
30
+ let used = false
31
+ let defined = false
32
+ for (const file of files) {
33
+ const content = await readFile(file, 'utf8')
34
+ if (!used && file.endsWith('.vue') && USAGE_RE.test(content)) used = true
35
+ if (!defined && DEFINITION_RE.test(content)) defined = true
36
+ if (used && defined) break
37
+ }
38
+
39
+ if (used && !defined) {
40
+ fail(
41
+ 'Клас `.n-admin-table` використовується у `.vue`, але не визначений у жодному `.scss`/`.css` (guide: style/admin_table.mdc) — додай фікс до app.scss',
42
+ 'missing-admin-table-style'
43
+ )
44
+ }
45
+ return reporter.result()
46
+ }
@@ -0,0 +1,21 @@
1
+ ## Кольори: quasar-variables.scss і app.scss
2
+
3
+ Основні кольори визначай виключно через стандартні Quasar-змінні: `$primary`, `$secondary`, `$accent`, `$positive`, `$negative`, `$warning`.
4
+
5
+ Якщо потрібен додатковий колір — визнач його в `quasar-variables.scss`, і **обов'язково** додай до `app.scss` відповідні `.text-*` / `.bg-*` класи:
6
+
7
+ ```scss
8
+ /* quasar-variables.scss */
9
+ $white-a1: color.adjust(white, $alpha: -0.85);
10
+ ```
11
+
12
+ ```scss
13
+ /* app.scss */
14
+ .text-white-a1 {
15
+ color: $white-a1 !important;
16
+ }
17
+
18
+ .bg-white-a1 {
19
+ background-color: $white-a1 !important;
20
+ }
21
+ ```
@@ -0,0 +1,3 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json"
3
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json",
3
+ "lint": {
4
+ "scope": "full",
5
+ "glob": ["**/*.vue", "**/*.scss", "**/*.css"]
6
+ }
7
+ }
@@ -0,0 +1,9 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/style/gap
4
+ resource: npm/rules/style/gap/
5
+ ---
6
+
7
+ | Файл | Тип |
8
+ | ------------------- | --------- |
9
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,15 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/style/gap/main.mjs
5
+ docgen:
6
+ crc: dcba23e0
7
+ ---
8
+
9
+ ## Огляд
10
+
11
+ Детектор concern-а `gap` (read-only, whole-repo): кожен суфікс утиліти
12
+ `.n-gap-{xs,sm,md,lg}`, використаний у `.vue`-файлі, має бути визначений хоч в одному
13
+ `.scss`/`.css`/`.vue` файлі проєкту — інакше порушення `missing-gap-style` для цього
14
+ суфіксу. Суфікси відстежуються незалежно один від одного, тож часткове покриття все одно
15
+ виявляє відсутній. Whole-repo сканування, не залежить від `ctx.files`.
@@ -0,0 +1,22 @@
1
+ ## Gap між flex/grid-елементами — .n-gap-*
2
+
3
+ Для відступів між плаваючими елементами (flex, grid) використовуй класи `.n-gap-*` замість `q-gutter-*`. Якщо класів немає в `app.scss` — додай:
4
+
5
+ ```scss
6
+ // GAP
7
+ .n-gap-xs {
8
+ gap: 4px;
9
+ }
10
+
11
+ .n-gap-sm {
12
+ gap: 8px;
13
+ }
14
+
15
+ .n-gap-md {
16
+ gap: 16px;
17
+ }
18
+
19
+ .n-gap-lg {
20
+ gap: 24px;
21
+ }
22
+ ```
@@ -0,0 +1,51 @@
1
+ /** @see ./docs/main.md */
2
+ import { readFile } from 'node:fs/promises'
3
+
4
+ import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
5
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
6
+
7
+ const RELEVANT_RE = /\.(?:vue|scss|css)$/u
8
+ const USAGE_RE = /\bn-gap-(xs|sm|md|lg)\b/gu
9
+ const DEFINITION_RE = /\.n-gap-(xs|sm|md|lg)\b/gu
10
+
11
+ /**
12
+ * Detector style/gap (read-only, whole-repo): кожен суфікс `.n-gap-{xs,sm,md,lg}`,
13
+ * використаний у `.vue`, має бути визначений хоч в одному `.scss`/`.css`/`.vue`
14
+ * (guide: `gap.mdc`). Крос-файлова перевірка usage↔definition — потребує whole-repo
15
+ * сканування незалежно від `ctx.files`.
16
+ * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
17
+ * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
18
+ */
19
+ export async function lint(ctx) {
20
+ const reporter = createViolationReporter(ctx)
21
+ const { fail } = reporter
22
+ const cwd = ctx.cwd
23
+
24
+ /** @type {string[]} */
25
+ const files = []
26
+ await walkDir(cwd, f => {
27
+ if (RELEVANT_RE.test(f)) files.push(f)
28
+ })
29
+
30
+ /** @type {Set<string>} */
31
+ const used = new Set()
32
+ /** @type {Set<string>} */
33
+ const defined = new Set()
34
+ for (const file of files) {
35
+ const content = await readFile(file, 'utf8')
36
+ if (file.endsWith('.vue')) {
37
+ for (const m of content.matchAll(USAGE_RE)) used.add(m[1])
38
+ }
39
+ for (const m of content.matchAll(DEFINITION_RE)) defined.add(m[1])
40
+ }
41
+
42
+ for (const suffix of used) {
43
+ if (!defined.has(suffix)) {
44
+ fail(
45
+ `Клас \`.n-gap-${suffix}\` використовується у \`.vue\`, але не визначений у жодному \`.scss\`/\`.css\` (guide: style/gap.mdc) — додай клас до app.scss`,
46
+ 'missing-gap-style'
47
+ )
48
+ }
49
+ }
50
+ return reporter.result()
51
+ }
@@ -0,0 +1,3 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json"
3
+ }
@@ -0,0 +1,7 @@
1
+ ## Quasar як стильова основа
2
+
3
+ У Vue-проектах використовуй **Quasar** як базову стильову систему:
4
+
5
+ - **Класи компонентів:** `q-pa-*`, `q-ma-*`, `q-mt-*`, `q-mb-*`, `row`, `col`, `col-*`, `items-center`, `justify-between`, `text-*`, `bg-*`, `shadow-*` тощо — стандартні утиліти Quasar.
6
+ - **Кольори:** використовуй Quasar CSS-змінні через класи (`text-primary`, `bg-accent`, `text-negative` тощо) або через SCSS-змінні (`$primary`, `$accent`) у `.scss`-файлах.
7
+ - **Не пиши власні утиліти**, якщо є відповідний Quasar-клас.
@@ -0,0 +1,7 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json",
3
+ "lint": {
4
+ "scope": "full",
5
+ "glob": ["**/*.vue", "**/*.scss", "**/*.css"]
6
+ }
7
+ }
@@ -0,0 +1,9 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/style/quasar_fixes
4
+ resource: npm/rules/style/quasar_fixes/
5
+ ---
6
+
7
+ | Файл | Тип |
8
+ | ------------------- | --------- |
9
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,16 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/style/quasar_fixes/main.mjs
5
+ docgen:
6
+ crc: 3eecca4c
7
+ ---
8
+
9
+ ## Огляд
10
+
11
+ Детектор concern-а `quasar_fixes` (read-only, whole-repo): якщо `.vue`-файл використовує
12
+ `<q-scroll-area>` або `<q-tooltip>`, десь у `.scss`/`.css`/`.vue` проєкту має бути
13
+ відповідний CSS-фікс (`.q-scrollarea` / `.q-tooltip`) — інакше порушення
14
+ `missing-quasar-fix`. iOS-zoom-фікс (тригер на `input`/`textarea`/`select`) навмисно не
15
+ перевіряється — надто загальний тригер, false-positive на майже будь-якій формі. Whole-repo
16
+ сканування, не залежить від `ctx.files`.
@@ -0,0 +1,57 @@
1
+ /** @see ./docs/main.md */
2
+ import { readFile } from 'node:fs/promises'
3
+
4
+ import { createViolationReporter } from '../../../scripts/lib/lint-surface/violation-reporter.mjs'
5
+ import { walkDir } from '../../../scripts/utils/walkDir.mjs'
6
+
7
+ const RELEVANT_RE = /\.(?:vue|scss|css)$/u
8
+
9
+ /**
10
+ * Пари (usage у `.vue` → очікуваний CSS-фікс) з guide `quasar_fixes.mdc`. Навмисно НЕ
11
+ * включено iOS-zoom-фікс (тригер `input`/`textarea`/`select` — занадто загальний,
12
+ * false-positive на майже будь-якій формі; консервативно залишено лише narrative).
13
+ */
14
+ const FIXES = [
15
+ { usage: /<q-scroll-area\b/u, definition: /\.q-scrollarea\b/u, name: 'q-scroll-area', selector: '.q-scrollarea' },
16
+ { usage: /<q-tooltip\b/u, definition: /\.q-tooltip\b/u, name: 'q-tooltip', selector: '.q-tooltip' }
17
+ ]
18
+
19
+ /**
20
+ * Detector style/quasar_fixes (read-only, whole-repo): якщо `.vue` використовує
21
+ * `<q-scroll-area>` або `<q-tooltip>`, у `.scss`/`.css`/`.vue` має бути відповідний
22
+ * CSS-фікс (guide: `quasar_fixes.mdc`). Крос-файлова перевірка usage↔definition —
23
+ * потребує whole-repo сканування незалежно від `ctx.files`.
24
+ * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
25
+ * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
26
+ */
27
+ export async function lint(ctx) {
28
+ const reporter = createViolationReporter(ctx)
29
+ const { fail } = reporter
30
+ const cwd = ctx.cwd
31
+
32
+ /** @type {string[]} */
33
+ const files = []
34
+ await walkDir(cwd, f => {
35
+ if (RELEVANT_RE.test(f)) files.push(f)
36
+ })
37
+
38
+ const used = new Set()
39
+ const defined = new Set()
40
+ for (const file of files) {
41
+ const content = await readFile(file, 'utf8')
42
+ for (const fix of FIXES) {
43
+ if (file.endsWith('.vue') && !used.has(fix.name) && fix.usage.test(content)) used.add(fix.name)
44
+ if (!defined.has(fix.name) && fix.definition.test(content)) defined.add(fix.name)
45
+ }
46
+ }
47
+
48
+ for (const fix of FIXES) {
49
+ if (used.has(fix.name) && !defined.has(fix.name)) {
50
+ fail(
51
+ `Компонент \`${fix.name}\` використовується у \`.vue\`, але фікс \`${fix.selector}\` відсутній у \`.scss\`/\`.css\` (guide: style/quasar_fixes.mdc) — додай фікс до app.scss`,
52
+ 'missing-quasar-fix'
53
+ )
54
+ }
55
+ }
56
+ return reporter.result()
57
+ }
@@ -0,0 +1,32 @@
1
+ ## Фікси компонентів Quasar
2
+
3
+ При використанні компонента `q-scroll-area` або `q-tooltip` додай до `app.scss` відповідні фікси. Аналогічно — фікс масштабування на iOS.
4
+
5
+ ```scss
6
+ // FIX стилі для прокручуваної області по висоті екрана
7
+ .q-scrollarea {
8
+ display: flex;
9
+ flex-direction: column;
10
+ height: auto;
11
+ min-height: 0;
12
+ max-height: 100%;
13
+
14
+ .scroll {
15
+ flex: 10000 1 0%;
16
+ }
17
+ }
18
+
19
+ // FIX tooltip
20
+ .q-tooltip {
21
+ font-size: 1em;
22
+ }
23
+
24
+ // FIX не зумувати на iOS
25
+ @media (width <= 600px) {
26
+ input,
27
+ textarea,
28
+ select {
29
+ font-size: 16px;
30
+ }
31
+ }
32
+ ```
@@ -81,8 +81,10 @@ jobs:
81
81
  contents: write
82
82
  id-token: write # OIDC для Infisical
83
83
  steps:
84
- # ... checkout, rust-toolchain, потім (rust.mdc вимагає кеш, zizmor фейлить
84
+ # ... checkout, потім (rust.mdc вимагає кеш, zizmor фейлить
85
85
  # cache-poisoning у тег-тригереному release — прийнятий ризик приглушуємо inline):
86
+ - uses: dtolnay/rust-toolchain@stable
87
+ with: { targets: aarch64-apple-darwin }
86
88
  - uses: Swatinem/rust-cache@v2 # zizmor: ignore[cache-poisoning]
87
89
  - name: Sync app version from tag
88
90
  run: |
@@ -93,11 +95,12 @@ jobs:
93
95
  - uses: Infisical/secrets-action@v1
94
96
  with: { secret-path: '/updater' }
95
97
  - uses: tauri-apps/tauri-action@v0
96
- with: { projectPath: app }
98
+ with: { projectPath: app, args: '--target aarch64-apple-darwin' }
97
99
  ```
98
100
 
99
101
  - **«Sync app version from tag» має йти перед кроком `tauri-apps/tauri-action`** — тег `vX.Y.Z` є єдиним джерелом версії для build-артефактів; `tauri.conf.json#version` у робочому дереві не редагується вручну (він там лишається тим, що востаннє поставив `n-rules release`, і синхронізується цим кроком лише в CI, не в git).
100
102
  - Секрети підпису — з Infisical: Apple-сертифікати (`secret-path: /apple`) і `TAURI_SIGNING_PRIVATE_KEY` (`secret-path: /updater`) — обидва потрібні `tauri-apps/tauri-action`, щоб зібрати підписаний DMG з updater-артефактами.
103
+ - **macOS-таргет — завжди `aarch64-apple-darwin`, ніколи `universal-apple-darwin`.** Без умовного галуження за кількістю `[[bin]]` у крейті: lipo-merge крок `tauri-action` зливає між арками лише головний GUI-бінарник, а будь-який додатковий `[[bin]]`-таргет лишається поза `universal-apple-darwin`-директорією — бандлер падає на `Failed to copy binary from ".../universal-apple-darwin/release/<bin>": ... does not exist`. Синхронно звузити `with.targets` кроку `dtolnay/rust-toolchain@…` до `aarch64-apple-darwin` (без `x86_64-apple-darwin`).
101
104
 
102
105
  ### `tauri.conf.json` — updater-артефакти й endpoint
103
106
 
@@ -0,0 +1,16 @@
1
+ {
2
+ "$schema": "https://unpkg.com/@7n/rules/schemas/concern.json",
3
+ "lint": {
4
+ "scope": "full",
5
+ "glob": [
6
+ "**/src/**/*.js",
7
+ "**/src/**/*.ts",
8
+ "**/src/**/*.jsx",
9
+ "**/src/**/*.tsx",
10
+ "**/src/**/*.vue",
11
+ "**/src-tauri/Cargo.toml",
12
+ "**/src-tauri/src/lib.rs",
13
+ "**/src-tauri/capabilities/*.json"
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,9 @@
1
+ ---
2
+ type: Directory Index
3
+ title: npm/rules/tauri/tool_surface
4
+ resource: npm/rules/tauri/tool_surface/
5
+ ---
6
+
7
+ | Файл | Тип |
8
+ | ------------------- | --------- |
9
+ | [main.mjs](main.md) | JS Module |
@@ -0,0 +1,24 @@
1
+ ---
2
+ type: JS Module
3
+ title: main.mjs
4
+ resource: npm/rules/tauri/tool_surface/main.mjs
5
+ docgen:
6
+ crc: 87b28b8d
7
+ ---
8
+
9
+ ## Огляд
10
+
11
+ Детектор concern-а `tool_surface`: для кожного Tauri-workspace знаходить Tauri-плагіни,
12
+ яких торкається JS/TS/Vue-код (через `@tauri-apps/plugin-*` import або прямий
13
+ `invoke('plugin:<slug>|...')`), і для кожного такого плагіна перевіряє три незалежні умови —
14
+ (1) crate-залежність присутня в `src-tauri/Cargo.toml`, (2) rust-ідентифікатор
15
+ (`tauri_plugin_<slug>`) згаданий у `src-tauri/src/lib.rs` (зареєстрований у builder-і),
16
+ (3) permission для нього є в `src-tauri/capabilities/*.json`. Відсутність будь-якої з трьох —
17
+ тихий рантайм-фейл без помилки компіляції, тому кожна дає окрему violation
18
+ (`tool-surface-plugin-dep-missing` / `-not-registered` / `-capability-missing`).
19
+
20
+ ## Публічний API
21
+
22
+ `PLUGIN_DEP_MISSING`, `PLUGIN_NOT_REGISTERED`, `PLUGIN_CAPABILITY_MISSING` — константи
23
+ причин violation. `lint(ctx)` — точка входу concern-у: обходить усі Tauri app workspaces
24
+ (`findTauriAppWorkspaces`) і перевіряє кожен.