@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.
- package/CHANGELOG.md +14 -0
- package/package.json +1 -1
- package/rules/abie/http_route_base/http_route_base.mdc +23 -1
- package/rules/adr/madr_format/concern.json +1 -0
- package/rules/adr/madr_format/madr_format.mdc +119 -0
- package/rules/bun/bunfig/bunfig.mdc +5 -0
- package/rules/bun/lint-surface/concern.json +3 -0
- package/rules/bun/lint-surface/lint-surface.mdc +13 -0
- package/rules/capacitor/platforms/docs/main.md +1 -1
- package/rules/capacitor/platforms/main.mjs +5 -1
- package/rules/capacitor/platforms/platforms.mdc +108 -0
- package/rules/changelog/consistency/comparison-models.mdc +46 -0
- package/rules/changelog/consistency/consistency.mdc +35 -0
- package/rules/docker/main.mdc +235 -2
- package/rules/image-avif/avif_generation/avif_generation.mdc +14 -0
- package/rules/js/check/check.mdc +26 -0
- package/rules/js/file-extensions/concern.json +3 -0
- package/rules/js/file-extensions/file-extensions.mdc +12 -0
- package/rules/js/jscpd_config/jscpd_config.mdc +28 -0
- package/rules/js/knip/knip.mdc +15 -0
- package/rules/js/utils_imports/utils_imports.mdc +15 -0
- package/rules/js-bun-db/connection/concern.json +3 -0
- package/rules/js-bun-db/connection/connection.mdc +42 -0
- package/rules/js-bun-db/package_json/package_json.mdc +15 -1
- package/rules/js-bun-db/pg_format_identifiers/concern.json +3 -0
- package/rules/js-bun-db/pg_format_identifiers/pg_format_identifiers.mdc +104 -0
- package/rules/js-bun-db/safety/safety.mdc +458 -0
- package/rules/js-mssql/main.mdc +130 -0
- package/rules/js-mssql/mssql-tvp/concern.json +3 -0
- package/rules/js-mssql/mssql-tvp/mssql-tvp.mdc +77 -0
- package/rules/js-run/configmap/configmap.mdc +6 -0
- package/rules/js-run/jsconfig/jsconfig.mdc +23 -0
- package/rules/js-run/package_json/package_json.mdc +6 -0
- package/rules/js-run/project-structure/concern.json +3 -0
- package/rules/js-run/project-structure/project-structure.mdc +11 -0
- package/rules/js-run/runtime/runtime.mdc +170 -0
- package/rules/js-run/scope/concern.json +3 -0
- package/rules/js-run/scope/scope.mdc +11 -0
- package/rules/k8s/hasura_configmap/hasura_configmap.mdc +6 -0
- package/rules/k8s/hpa_pdb/hpa_pdb.mdc +134 -0
- package/rules/k8s/kubeconform/kubeconform.mdc +38 -0
- package/rules/k8s/kustomization/kustomization.mdc +73 -0
- package/rules/k8s/main.mdc +68 -0
- package/rules/k8s/manifest/manifest.mdc +37 -0
- package/rules/k8s/manifests/docs/fix-manifests.md +3 -1
- package/rules/k8s/manifests/fix-manifests.mjs +11 -0
- package/rules/k8s/manifests/main.mjs +28 -0
- package/rules/k8s/network_policy/network_policy.mdc +33 -0
- package/rules/nginx-default-tpl/http-route/concern.json +1 -0
- package/rules/nginx-default-tpl/http-route/http-route.mdc +54 -0
- package/rules/nginx-default-tpl/template/template.mdc +152 -0
- package/rules/php/tooling/tooling.mdc +7 -6
- package/rules/python/pyproject_toml/pyproject_toml.mdc +17 -1
- package/rules/python/tooling/tooling.mdc +9 -10
- package/rules/rego/main.mdc +14 -0
- package/rules/rust/check/check.mdc +16 -0
- package/rules/style/admin_table/admin_table.mdc +88 -0
- package/rules/style/admin_table/concern.json +7 -0
- package/rules/style/admin_table/docs/index.md +9 -0
- package/rules/style/admin_table/docs/main.md +14 -0
- package/rules/style/admin_table/main.mjs +46 -0
- package/rules/style/colors/colors.mdc +21 -0
- package/rules/style/colors/concern.json +3 -0
- package/rules/style/gap/concern.json +7 -0
- package/rules/style/gap/docs/index.md +9 -0
- package/rules/style/gap/docs/main.md +15 -0
- package/rules/style/gap/gap.mdc +22 -0
- package/rules/style/gap/main.mjs +51 -0
- package/rules/style/quasar/concern.json +3 -0
- package/rules/style/quasar/quasar.mdc +7 -0
- package/rules/style/quasar_fixes/concern.json +7 -0
- package/rules/style/quasar_fixes/docs/index.md +9 -0
- package/rules/style/quasar_fixes/docs/main.md +16 -0
- package/rules/style/quasar_fixes/main.mjs +57 -0
- package/rules/style/quasar_fixes/quasar_fixes.mdc +32 -0
- package/rules/tauri/release/release.mdc +5 -2
- package/rules/tauri/tool_surface/concern.json +16 -0
- package/rules/tauri/tool_surface/docs/index.md +9 -0
- package/rules/tauri/tool_surface/docs/main.md +24 -0
- package/rules/tauri/tool_surface/main.mjs +145 -0
- package/rules/tauri/tool_surface/tool_surface.mdc +29 -0
- package/rules/test/vitest-api-conventions/concern.json +7 -0
- package/rules/test/vitest-api-conventions/docs/index.md +9 -0
- package/rules/test/vitest-api-conventions/docs/main.md +40 -0
- package/rules/test/vitest-api-conventions/main.mjs +186 -0
- package/rules/test/vitest-api-conventions/vitest-api-conventions.mdc +129 -0
- package/rules/text/cspell/cspell.mdc +18 -0
- package/rules/text/markdownlint/markdownlint.mdc +4 -0
- package/rules/text/run-dotenv-linter/run-dotenv-linter.mdc +17 -0
- package/rules/text/run-shellcheck/run-shellcheck.mdc +17 -0
- package/rules/text/run-v8r/run-v8r.mdc +23 -0
- package/rules/vue/composition-api/composition-api.mdc +82 -0
- package/rules/vue/composition-api/concern.json +3 -0
- package/rules/vue/main.mdc +1 -1
- package/rules/vue/nheader-layout/concern.json +3 -0
- package/rules/vue/nheader-layout/nheader-layout.mdc +171 -0
- package/rules/vue/packages/packages.mdc +56 -0
- package/rules/vue/quasar-ui/concern.json +3 -0
- package/rules/vue/quasar-ui/quasar-ui.mdc +32 -0
- package/rules/vue/structure/concern.json +3 -0
- package/rules/vue/structure/structure.mdc +101 -0
- package/rules/vue/testing/concern.json +3 -0
- package/rules/vue/testing/testing.mdc +40 -0
- package/rules/vue/tfm-translations/concern.json +7 -0
- package/rules/vue/tfm-translations/docs/main.md +29 -0
- package/rules/vue/tfm-translations/main.mjs +55 -0
- package/rules/vue/tfm-translations/tfm-translations.mdc +32 -0
- package/rules/vue/vite-config/concern.json +3 -0
- package/rules/vue/vite-config/vite-config.mdc +153 -0
- package/rules/vue/vite-env/concern.json +3 -0
- 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,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,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,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,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,
|
|
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,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`) і перевіряє кожен.
|