@nitra/cursor 1.8.83 → 1.8.85
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/README.md +9 -12
- package/bin/n-cursor.js +2 -2
- package/mdc/k8s.mdc +85 -1
- package/mdc/style-lint.mdc +1 -1
- package/mdc/text.mdc +87 -5
- package/mdc/vue.mdc +1 -1
- package/package.json +1 -1
- package/scripts/check-abie.mjs +1 -0
- package/scripts/check-k8s.mjs +43 -2
- package/scripts/check-text.mjs +74 -3
- package/mdc/js-format.mdc +0 -103
- package/scripts/check-js-format.mjs +0 -96
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
Репозиторій `@nitra/cursor` містить cursor-правила у директорії `mdc/`. CLI копіює обрані правила з **каталогу `mdc/` того пакету, з якого виконується `bin/n-cursor.js`**: після `npm i` / `bun add` це зазвичай `node_modules/@nitra/cursor/mdc`; при **`npx @nitra/cursor`** пакет потрапляє в **кеш npx/npm**, і правила читаються з тієї розпакованої копії (у корені проєкту залежність не обов’язкова). Жодних окремих HTTP-запитів до CDN для файлів правил немає — лише те, що вже є в tarball пакету.
|
|
8
8
|
|
|
9
|
-
Наприклад, правило `mdc/
|
|
9
|
+
Наприклад, правило `mdc/text.mdc` буде збережено як `.cursor/rules/n-text.mdc`.
|
|
10
10
|
|
|
11
11
|
## Підготовка
|
|
12
12
|
|
|
@@ -15,19 +15,18 @@
|
|
|
15
15
|
```json
|
|
16
16
|
{
|
|
17
17
|
"$schema": "https://unpkg.com/@nitra/cursor/schemas/n-cursor.json",
|
|
18
|
-
"rules": ["
|
|
18
|
+
"rules": ["npm-module", "text"],
|
|
19
19
|
"skills": ["fix"]
|
|
20
20
|
}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
23
|
Доступні правила:
|
|
24
24
|
|
|
25
|
-
| Назва | Опис
|
|
26
|
-
| ------------ |
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `k8s` | Kubernetes YAML, Kustomize, kubeconform |
|
|
25
|
+
| Назва | Опис |
|
|
26
|
+
| ------------ | ----------------------------------------------- |
|
|
27
|
+
| `npm-module` | Структура репозиторію для npm-модуля (bun mono) |
|
|
28
|
+
| `text` | Текст, oxfmt, cspell, markdownlint, v8r, CI |
|
|
29
|
+
| `k8s` | Kubernetes YAML, Kustomize, kubeconform |
|
|
31
30
|
|
|
32
31
|
Щоб використовувати конкретну версію правил, оновіть залежність `@nitra/cursor` у проєкті (`bun add -d @nitra/cursor@<версія>` тощо). Поле `version` у `.n-cursor.json`, якщо воно лишилось у старих конфігах, **ігнорується**.
|
|
33
32
|
|
|
@@ -71,13 +70,12 @@ CLI автоматично (команда завантаження правил
|
|
|
71
70
|
```
|
|
72
71
|
🔧 @nitra/cursor — завантаження cursor-правил
|
|
73
72
|
|
|
74
|
-
📋 Правил до завантаження:
|
|
75
|
-
⬇ js-format → .cursor/rules/n-js-format.mdc ... ✅
|
|
73
|
+
📋 Правил до завантаження: 2
|
|
76
74
|
⬇ npm-module → .cursor/rules/n-npm-module.mdc ... ✅
|
|
77
75
|
⬇ text → .cursor/rules/n-text.mdc ... ✅
|
|
78
76
|
📝 Оновлено AGENTS.md з AGENTS.template.md
|
|
79
77
|
|
|
80
|
-
✨ Готово:
|
|
78
|
+
✨ Готово: 2 завантажено, 0 з помилками
|
|
81
79
|
```
|
|
82
80
|
|
|
83
81
|
## Структура пакету
|
|
@@ -86,7 +84,6 @@ CLI автоматично (команда завантаження правил
|
|
|
86
84
|
npm/
|
|
87
85
|
├── AGENTS.template.md # шаблон AGENTS.md для цільових репозиторіїв (потрапляє в npm-архів)
|
|
88
86
|
├── mdc/ # cursor-правила (без префікса n-; після синку — .cursor/rules/n-<id>.mdc)
|
|
89
|
-
│ ├── js-format.mdc
|
|
90
87
|
│ ├── npm-module.mdc
|
|
91
88
|
│ └── text.mdc
|
|
92
89
|
├── skills/ # skills (каталоги <id>/; після синку — .cursor/skills/n-<id>/)
|
package/bin/n-cursor.js
CHANGED
|
@@ -204,8 +204,8 @@ async function readConfig(paths = {}) {
|
|
|
204
204
|
|
|
205
205
|
/**
|
|
206
206
|
* Витягує чисте ім'я файлу правила (без шляху, але зберігає .mdc)
|
|
207
|
-
* "npm/mdc/
|
|
208
|
-
* "
|
|
207
|
+
* "npm/mdc/text.mdc" → "text.mdc"
|
|
208
|
+
* "text" → "text.mdc"
|
|
209
209
|
* @param {string} ruleName шлях або базове ім'я, з суфіксом .mdc або без
|
|
210
210
|
* @returns {string} лише ім'я файлу з суфіксом .mdc
|
|
211
211
|
*/
|
package/mdc/k8s.mdc
CHANGED
|
@@ -15,6 +15,8 @@ alwaysApply: false
|
|
|
15
15
|
|
|
16
16
|
Далі — вміст маніфесту. Зайвий порожній рядок між коментарем і YAML не додавай, якщо в проєкті не прийнято інше.
|
|
17
17
|
|
|
18
|
+
**Виняток — без modeline:** `apiVersion: alb.yc.io/v1alpha1`, `kind: HttpBackendGroup` (Yandex ALB) — рядка **`# yaml-language-server: $schema=…`** у файлі **не** має бути (ні в першому рядку, ні далі). Перший рядок — одразу YAML (`apiVersion:` тощо). Перевірка — **`check-k8s.mjs`**.
|
|
19
|
+
|
|
18
20
|
**Розширення:** усі маніфести під **`k8s`**, включно з **`kustomization.yaml`**, — лише **`.yaml`** (розширення **`.yml`** не використовуй).
|
|
19
21
|
|
|
20
22
|
**Dockerfile / hadolint** — окреме правило **`docker.mdc`** і **`npx @nitra/cursor check docker`**.
|
|
@@ -106,6 +108,88 @@ resources: {}
|
|
|
106
108
|
|
|
107
109
|
Образ **`hasura/graphql-engine`**: дозволений лише канонічний тег із константи **`HASURA_GRAPHQL_ENGINE_IMAGE`** у **`check-k8s.mjs`** (допускається префікс **`docker.io/`**); решта — помилка **check k8s**.
|
|
108
110
|
|
|
111
|
+
### HTTPRoute для Deployment з `hasura/graphql-engine`
|
|
112
|
+
|
|
113
|
+
Якщо для такого **Deployment** описано **`HTTPRoute`**, **`spec.rules`** мають відповідати канону нижче: редірект **`/ql`** та **`/ql/`** на **`/ql/console`** (**`302`**), правило з **`PathPrefix` `/ql`**, **`URLRewrite`** префікса на **`/`**, окреме правило для **WebSocket** (**`Upgrade: websocket`**) з **`RequestHeaderModifier`** (прибрати **`Authorization`** — авторизація для WebSocket іде всередині messages), далі **`PathPrefix` `/`** на той самий backend.
|
|
114
|
+
|
|
115
|
+
**`parentRefs`**, **`hostnames`**, **`metadata.namespace`** / **`name`** підлаштуй під середовище. У **`backendRefs.name`** вказуй **headless** **Service** з суфіксом **`-hl`** (див. розділ **«Service: `svc.yaml` і `svc-hl.yaml`»**); у прикладі **`db-h-hl`** заміни на фактичне ім’я.
|
|
116
|
+
|
|
117
|
+
```yaml
|
|
118
|
+
# yaml-language-server: $schema=https://datreeio.github.io/CRDs-catalog/gateway.networking.k8s.io/httproute_v1beta1.json
|
|
119
|
+
apiVersion: gateway.networking.k8s.io/v1beta1
|
|
120
|
+
kind: HTTPRoute
|
|
121
|
+
metadata:
|
|
122
|
+
name: db-h
|
|
123
|
+
namespace: dev
|
|
124
|
+
spec:
|
|
125
|
+
parentRefs:
|
|
126
|
+
- name: gw
|
|
127
|
+
namespace: dev
|
|
128
|
+
sectionName: https
|
|
129
|
+
hostnames:
|
|
130
|
+
- abie.cloud
|
|
131
|
+
rules:
|
|
132
|
+
- matches:
|
|
133
|
+
- path:
|
|
134
|
+
type: Exact
|
|
135
|
+
value: /ql
|
|
136
|
+
filters:
|
|
137
|
+
- type: RequestRedirect
|
|
138
|
+
requestRedirect:
|
|
139
|
+
path:
|
|
140
|
+
type: ReplaceFullPath
|
|
141
|
+
replaceFullPath: /ql/console
|
|
142
|
+
statusCode: 302
|
|
143
|
+
- matches:
|
|
144
|
+
- path:
|
|
145
|
+
type: Exact
|
|
146
|
+
value: /ql/
|
|
147
|
+
filters:
|
|
148
|
+
- type: RequestRedirect
|
|
149
|
+
requestRedirect:
|
|
150
|
+
path:
|
|
151
|
+
type: ReplaceFullPath
|
|
152
|
+
replaceFullPath: /ql/console
|
|
153
|
+
statusCode: 302
|
|
154
|
+
- matches:
|
|
155
|
+
- path:
|
|
156
|
+
type: PathPrefix
|
|
157
|
+
value: /ql
|
|
158
|
+
filters:
|
|
159
|
+
- type: URLRewrite
|
|
160
|
+
urlRewrite:
|
|
161
|
+
path:
|
|
162
|
+
type: ReplacePrefixMatch
|
|
163
|
+
replacePrefixMatch: /
|
|
164
|
+
backendRefs:
|
|
165
|
+
- name: db-h-hl
|
|
166
|
+
port: 8080
|
|
167
|
+
# У WebSocket авторизація йде всередині messages
|
|
168
|
+
- matches:
|
|
169
|
+
- path:
|
|
170
|
+
type: PathPrefix
|
|
171
|
+
value: /
|
|
172
|
+
headers:
|
|
173
|
+
- type: Exact
|
|
174
|
+
name: Upgrade
|
|
175
|
+
value: websocket
|
|
176
|
+
filters:
|
|
177
|
+
- type: RequestHeaderModifier
|
|
178
|
+
requestHeaderModifier:
|
|
179
|
+
remove:
|
|
180
|
+
- Authorization
|
|
181
|
+
backendRefs:
|
|
182
|
+
- name: db-h-hl
|
|
183
|
+
port: 8080
|
|
184
|
+
- matches:
|
|
185
|
+
- path:
|
|
186
|
+
type: PathPrefix
|
|
187
|
+
value: /
|
|
188
|
+
backendRefs:
|
|
189
|
+
- name: db-h-hl
|
|
190
|
+
port: 8080
|
|
191
|
+
```
|
|
192
|
+
|
|
109
193
|
## Service: заборонені анотації GKE
|
|
110
194
|
|
|
111
195
|
У **`kind: Service`** не додавай у **`metadata.annotations`** **`cloud.google.com/neg`** і **`cloud.google.com/backend-config`** (legacy під Ingress / старе балансування GKE). **check k8s** падає, якщо ключ є.
|
|
@@ -224,7 +308,7 @@ patches:
|
|
|
224
308
|
|
|
225
309
|
**`npx @nitra/cursor check k8s`** — програмні критерії в **JSDoc на початку** **`npm/scripts/check-k8s.mjs`**. Якщо під **`k8s`** немає **`*.yaml`** — крок пропущено. Канон **`$schema`** для редактора — розділ **«Визначення схеми YAML`** нижче.
|
|
226
310
|
|
|
227
|
-
**Не входить у check k8s:** наприклад **ReferenceGrant** і доступ між **namespace** (лише рекомендації тут), **kubeconform** / **kubescape** — це **`bun run lint-k8s`**.
|
|
311
|
+
**Не входить у check k8s:** наприклад **ReferenceGrant** і доступ між **namespace** (лише рекомендації тут), повна структура **`HTTPRoute`** для **Hasura** (канон — у розділі про **`hasura/graphql-engine`**), **kubeconform** / **kubescape** — це **`bun run lint-k8s`**.
|
|
228
312
|
|
|
229
313
|
## Коли застосовувати (агентам)
|
|
230
314
|
|
package/mdc/style-lint.mdc
CHANGED
|
@@ -7,7 +7,7 @@ version: '1.2'
|
|
|
7
7
|
## Генерація та редагування стилів (Cursor і інші агенти)
|
|
8
8
|
|
|
9
9
|
- **Джерело правил:** перед тим як писати або суттєво змінювати **`.css`**, **`.scss`** або стилі в **`.vue`**, переглянь у корені проєкту (і в релевантних пакетах монорепо, якщо є) поле **`stylelint`** у **`package.json`** (зокрема `extends`), наявні **`.stylelintrc.*`**, **`stylelint.config.*`** та **`.stylelintignore`**. Не покладайся на «типові» правила stylelint з пам’яті — дотримуйся **проєктного** **`@nitra/stylelint-config`** і будь-яких локальних доповнень у репозиторії.
|
|
10
|
-
- **Форматування** узгоджуй з **`n-
|
|
10
|
+
- **Форматування** узгоджуй з **`n-text.mdc`** (oxfmt / `.oxfmtrc.json` для css, scss тощо), щоб форматер і stylelint не суперечили один одному.
|
|
11
11
|
- **Запуск stylelint:** лише **`npx stylelint`**. Локально — через скрипт **`lint-style`** (`bun run lint-style`); у **GitHub Actions** у кроці **`run`** викликай `npx stylelint '**/*.{css,scss,vue}' --fix` напряму (не через **`bun run lint-style`**). Не використовуй **`bunx stylelint`**. Після змін запускай **`bun run lint-style`** і виправляй усе, що лишилось після auto-fix; за потреби — повний набір `lint-*` (навичка **`n-fix`**).
|
|
12
12
|
- **Не розширюй винятки:** не додавай зайві **`stylelint-disable`** без потреби; краще підлаштувати стилі під правила проєкту.
|
|
13
13
|
|
package/mdc/text.mdc
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Обробка та перевірка текстових
|
|
2
|
+
description: Обробка та перевірка текстових файлів, oxfmt, cspell, markdownlint-cli2, v8r, CI
|
|
3
3
|
alwaysApply: true
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.25'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
**cspell**, **markdownlint-cli2**, **[v8r](https://chris48s.github.io/v8r/)** ([Schema Store](https://www.schemastore.org/)), розширення **DavidAnson.vscode-markdownlint**, workflow **`lint-text`**.
|
|
7
|
+
**oxfmt** (`.oxfmtrc.json`, редактор), **cspell**, **markdownlint-cli2**, **[v8r](https://chris48s.github.io/v8r/)** ([Schema Store](https://www.schemastore.org/)), розширення **DavidAnson.vscode-markdownlint**, workflow **`lint-text`**.
|
|
8
8
|
|
|
9
9
|
```json title=".vscode/extensions.json"
|
|
10
10
|
{
|
|
@@ -24,10 +24,92 @@ version: '1.24'
|
|
|
24
24
|
"files.associations": {
|
|
25
25
|
"*.env.*": "env",
|
|
26
26
|
"*.env": "env"
|
|
27
|
-
}
|
|
27
|
+
},
|
|
28
|
+
"editor.formatOnSave": true,
|
|
29
|
+
"[css]": {
|
|
30
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
31
|
+
},
|
|
32
|
+
"[graphql]": {
|
|
33
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
34
|
+
},
|
|
35
|
+
"[handlebars]": {
|
|
36
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
37
|
+
},
|
|
38
|
+
"[html]": {
|
|
39
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
40
|
+
},
|
|
41
|
+
"[javascript]": {
|
|
42
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
43
|
+
},
|
|
44
|
+
"[json]": {
|
|
45
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
46
|
+
},
|
|
47
|
+
"[json5]": {
|
|
48
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
49
|
+
},
|
|
50
|
+
"[jsonc]": {
|
|
51
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
52
|
+
},
|
|
53
|
+
"[less]": {
|
|
54
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
55
|
+
},
|
|
56
|
+
"[markdown]": {
|
|
57
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
58
|
+
},
|
|
59
|
+
"[mdx]": {
|
|
60
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
61
|
+
},
|
|
62
|
+
"[scss]": {
|
|
63
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
64
|
+
},
|
|
65
|
+
"[toml]": {
|
|
66
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
67
|
+
},
|
|
68
|
+
"[typescript]": {
|
|
69
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
70
|
+
},
|
|
71
|
+
"[vue]": {
|
|
72
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
73
|
+
},
|
|
74
|
+
"[yaml]": {
|
|
75
|
+
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
76
|
+
},
|
|
77
|
+
"oxc.path.oxfmt": "/opt/homebrew/bin/oxfmt"
|
|
28
78
|
}
|
|
29
79
|
```
|
|
30
80
|
|
|
81
|
+
У корені проєкту має бути файл з правилами форматування для **oxfmt**:
|
|
82
|
+
|
|
83
|
+
```json title=".oxfmtrc.json"
|
|
84
|
+
{
|
|
85
|
+
"ignorePatterns": ["**/hasura/metadata/**", "**/schema.graphql"],
|
|
86
|
+
"arrowParens": "avoid",
|
|
87
|
+
"printWidth": 120,
|
|
88
|
+
"bracketSpacing": true,
|
|
89
|
+
"bracketSameLine": true,
|
|
90
|
+
"embeddedLanguageFormatting": "auto",
|
|
91
|
+
"endOfLine": "lf",
|
|
92
|
+
"htmlWhitespaceSensitivity": "css",
|
|
93
|
+
"insertPragma": false,
|
|
94
|
+
"jsxSingleQuote": true,
|
|
95
|
+
"proseWrap": "preserve",
|
|
96
|
+
"quoteProps": "as-needed",
|
|
97
|
+
"requirePragma": false,
|
|
98
|
+
"semi": false,
|
|
99
|
+
"singleQuote": true,
|
|
100
|
+
"tabWidth": 2,
|
|
101
|
+
"trailingComma": "none",
|
|
102
|
+
"useTabs": false,
|
|
103
|
+
"vueIndentScriptAndStyle": false
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Поле **`ignorePatterns`** додавай за потреби (наприклад згенеровані каталоги); якщо виключень немає — ключ можна опустити.
|
|
108
|
+
|
|
109
|
+
Також потрібно прибрати, якщо є в проєкті, модуль **`@nitra/prettier-config`**, **prettier** та всі виклики prettier і налаштування для нього.
|
|
110
|
+
|
|
111
|
+
Завжди пиши **JSDoc** до функцій та методів.
|
|
112
|
+
|
|
31
113
|
**`package.json`:** скрипт **`lint-text`** і devDependencies **`@nitra/cspell-dict`**. Для української додай **`@cspell/dict-uk-ua`**. **`markdownlint-cli2`** викликай у `lint-text` лише через **`bunx markdownlint-cli2`**, не додавай пакет до devDependencies. **`v8r`** лише через **`bunx v8r`** (зазвичай **`bunx v8r`**), не в devDependencies. Окремий пакет **`markdownlint`** не потрібний.
|
|
32
114
|
|
|
33
115
|
У v8r **немає** прапорця тихого режиму; рекомендовано скрипт **`run-v8r.mjs`** з репозиторію пакета `@nitra/cursor` (`npm/scripts/run-v8r.mjs`): один виклик у `lint-text` — під капотом послідовні **`bunx v8r`** для кожного типу (**json**, **json5**, **yml**, **yaml**, **toml**), бо один процес v8r з кількома глобами падає з **98**, якщо хоч один glob порожній, і тоді інші розширення не перевіряються. Вивід при кодах **0** і **98** не показується. Каталог схем **`schemas/v8r-catalog.json`** пакета `@nitra/cursor` скрипт підставляє в v8r сам. За бажання можна передати власні glob-и аргументами скрипта. Шлях до скрипта: `./npm/scripts/…`, `./scripts/…` після копіювання, або `node_modules/@nitra/cursor/scripts/…`.
|
|
@@ -215,4 +297,4 @@ jobs:
|
|
|
215
297
|
|
|
216
298
|
## Перевірка
|
|
217
299
|
|
|
218
|
-
`npx @nitra/cursor check text`
|
|
300
|
+
`npx @nitra/cursor check text` (охоплює oxfmt, cspell, markdownlint, v8r, CI для `lint-text`)
|
package/mdc/vue.mdc
CHANGED
|
@@ -108,7 +108,7 @@ const additionalInstructions = `
|
|
|
108
108
|
|
|
109
109
|
### Інструменти (узгоджено з Vite і цим правилом)
|
|
110
110
|
|
|
111
|
-
- Якість коду: **ESLint** + **eslint-plugin-vue**; форматування — **oxfmt**, див. `
|
|
111
|
+
- Якість коду: **ESLint** + **eslint-plugin-vue**; форматування — **oxfmt**, див. `text.mdc`.
|
|
112
112
|
- Збірка та dev-сервер — **Vite**
|
|
113
113
|
- **Vue Devtools** для дебагу; продакшен-збірка — **`vite build`**, оптимізація асетів і кешування на рівні деплою / CDN.
|
|
114
114
|
|
package/package.json
CHANGED
package/scripts/check-abie.mjs
CHANGED
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* **k8s:** якщо під деревом із сегментом **`k8s`** є YAML з **`kind: Deployment`**, у тій самій директорії
|
|
14
14
|
* має існувати **`hc.yaml`** із **`HealthCheckPolicy`** (**`networking.gke.io/v1`**), modeline **`$schema`**
|
|
15
15
|
* як у abie.mdc, **`/healthz`**, порт **8080**, **`targetRef`** на **Service** з тим самим **`metadata.name`**.
|
|
16
|
+
* Загальні вимоги до **`# yaml-language-server: $schema`** для інших YAML під **`k8s`** — у **check-k8s.mjs** / **k8s.mdc** (наприклад **HttpBackendGroup** `alb.yc.io/v1alpha1` — **без** modeline).
|
|
16
17
|
* Якщо в дереві **k8s** є **HealthCheckPolicy**, перевіряється **`ru/kustomization.yaml`** з patch **`$patch: delete`**
|
|
17
18
|
* (логіка вмісту — **`ruKustomizationHasHealthCheckDeletePatch`** у **check-k8s.mjs**, узгоджено з **k8s.mdc**).
|
|
18
19
|
*
|
package/scripts/check-k8s.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Перший рядок `# yaml-language-server: $schema=…`, без дублікатів, розширення `.yaml`
|
|
5
5
|
* (окрім `kustomization.yaml`); URL схеми за першим документом — kustomization / yannh / datree
|
|
6
|
+
* (**виняток:** `apiVersion: alb.yc.io/v1alpha1`, `kind: HttpBackendGroup` — рядка `# yaml-language-server:` у файлі бути не має).
|
|
6
7
|
* (datree за замовчуванням: GitHub Pages `https://datreeio.github.io/CRDs-catalog/…`).
|
|
7
8
|
*
|
|
8
9
|
* Додатково: у кожному YAML-документі з **`kind: Deployment`** у кожного контейнера
|
|
@@ -47,6 +48,8 @@
|
|
|
47
48
|
* **`apiVersion`, `kind`, `type`** (для CRD без поля `type` у маніфесті — зірочка **`*`** як третій
|
|
48
49
|
* компонент). Спочатку шукається збіг за фактичним `type`, потім за **`*`**.
|
|
49
50
|
* Dockerfile — правило docker.mdc, скрипт check-docker.mjs.
|
|
51
|
+
*
|
|
52
|
+
* Структура **`HTTPRoute`** для **Deployment** з образом **`hasura/graphql-engine`** (редиректи **`/ql`**, **WebSocket**, **`URLRewrite`**) — лише в **k8s.mdc**, автоматично не звіряється.
|
|
50
53
|
*/
|
|
51
54
|
import { existsSync } from 'node:fs'
|
|
52
55
|
import { readFile, stat, unlink } from 'node:fs/promises'
|
|
@@ -669,6 +672,18 @@ function extractApiVersionAndKind(doc) {
|
|
|
669
672
|
}
|
|
670
673
|
}
|
|
671
674
|
|
|
675
|
+
/**
|
|
676
|
+
* Чи перший YAML-документ (до `---`) — **HttpBackendGroup** з API **alb.yc.io/v1alpha1** (Yandex ALB).
|
|
677
|
+
* Для таких файлів **check-k8s** не вимагає modeline `# yaml-language-server: $schema=…` і забороняє його.
|
|
678
|
+
* @param {string} yamlBody вміст файлу або фрагмент після modeline
|
|
679
|
+
* @returns {boolean} true, якщо `apiVersion`/`kind` першого документа збігаються з винятком
|
|
680
|
+
*/
|
|
681
|
+
export function k8sYamlFirstDocIsAlbYcHttpBackendGroup(yamlBody) {
|
|
682
|
+
const first = firstYamlDocument(yamlBody)
|
|
683
|
+
const { apiVersion, kind } = extractApiVersionAndKind(first)
|
|
684
|
+
return apiVersion === 'alb.yc.io/v1alpha1' && kind === 'HttpBackendGroup'
|
|
685
|
+
}
|
|
686
|
+
|
|
672
687
|
/**
|
|
673
688
|
* Чи вміст overlay **`ru/kustomization.yaml`** містить Kustomize patch видалення **HealthCheckPolicy**.
|
|
674
689
|
* @param {string} raw повний текст файлу
|
|
@@ -1597,12 +1612,38 @@ async function checkK8sYamlFile(abs, root, fail, pass, kustomizeManagedRel) {
|
|
|
1597
1612
|
return
|
|
1598
1613
|
}
|
|
1599
1614
|
|
|
1600
|
-
const
|
|
1601
|
-
|
|
1615
|
+
const firstLineIsModeline = MODELINE_RE.test(lines[0])
|
|
1616
|
+
const bodyForFirstDoc = k8sYamlBodyForDocumentParse(lines)
|
|
1617
|
+
const isAlbHttpBackendGroup = k8sYamlFirstDocIsAlbYcHttpBackendGroup(bodyForFirstDoc)
|
|
1618
|
+
|
|
1619
|
+
if (isAlbHttpBackendGroup) {
|
|
1620
|
+
if (firstLineIsModeline) {
|
|
1621
|
+
fail(
|
|
1622
|
+
`${rel}: для kind HttpBackendGroup (apiVersion alb.yc.io/v1alpha1) не задавай # yaml-language-server: $schema — прибери перший рядок modeline (k8s.mdc)`
|
|
1623
|
+
)
|
|
1624
|
+
return
|
|
1625
|
+
}
|
|
1626
|
+
if (countSchemaModelines(lines) > 0) {
|
|
1627
|
+
fail(
|
|
1628
|
+
`${rel}: для kind HttpBackendGroup (apiVersion alb.yc.io/v1alpha1) не використовуй # yaml-language-server: $schema у файлі (k8s.mdc)`
|
|
1629
|
+
)
|
|
1630
|
+
return
|
|
1631
|
+
}
|
|
1632
|
+
const body = lines.join('\n')
|
|
1633
|
+
scanIngressInYamlDocuments(rel, body, fail)
|
|
1634
|
+
pass(`${rel}: HttpBackendGroup (alb.yc.io/v1alpha1) — modeline $schema не застосовується (k8s.mdc)`)
|
|
1635
|
+
const kustomizeManaged = kustomizeManagedRel.has(rel)
|
|
1636
|
+
validateK8sYamlPolicyDocuments(rel, baseLower, body, fail, kustomizeManaged)
|
|
1637
|
+
scanGatewayApiRouteBackendRefsInYamlBody(rel, body, fail)
|
|
1638
|
+
return
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
if (!firstLineIsModeline) {
|
|
1602
1642
|
fail(`${rel}: перший рядок має бути коментарем # yaml-language-server: $schema=<url> (без префіксів перед #)`)
|
|
1603
1643
|
return
|
|
1604
1644
|
}
|
|
1605
1645
|
|
|
1646
|
+
const m = /** @type {RegExpMatchArray} */ (lines[0].match(MODELINE_RE))
|
|
1606
1647
|
const schemaUrl = m[1]
|
|
1607
1648
|
if (countSchemaModelines(lines) > 1) {
|
|
1608
1649
|
fail(`${rel}: кілька рядків yaml-language-server $schema — лиш один modeline на файл (див. k8s.mdc)`)
|
package/scripts/check-text.mjs
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Перевіряє текстовий стек за правилом text.mdc.
|
|
2
|
+
* Перевіряє текстовий стек і форматування за правилом text.mdc.
|
|
3
|
+
*
|
|
4
|
+
* oxfmt: `.oxfmtrc.json` з обовʼязковими ключами, VSCode (formatOnSave, defaultFormatter для js/ts/json/vue/css/html),
|
|
5
|
+
* відсутність Prettier у конфігах і залежностях.
|
|
3
6
|
*
|
|
4
7
|
* cspell, markdownlint через `bunx markdownlint-cli2` у `lint-text` (без оголошення пакета в package.json), заборона
|
|
5
8
|
* `markdownlint-cli2` у dependencies/devDependencies, v8r (`run-v8r.mjs` або чотири `bunx v8r`),
|
|
6
9
|
* `.v8rignore` (vscode JSON),
|
|
7
|
-
* workflow `lint-text.yml`, розширення VSCode
|
|
10
|
+
* workflow `lint-text.yml`, розширення VSCode (markdownlint, oxc).
|
|
8
11
|
*
|
|
9
12
|
* Якщо є `.cursor/rules/n-text.mdc` і/або `npm/mdc/text.mdc` — перевіряє наявність абзацу про український
|
|
10
13
|
* апостроф (U+0027 vs U+2019) і приклад з символом U+2019 у тексті.
|
|
@@ -43,7 +46,7 @@ function verifyUkApostropheRuleParagraph(filePath, body, failFn, passFn) {
|
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
/**
|
|
46
|
-
* Перевіряє відповідність проєкту правилам text.mdc (cspell, markdownlint через bunx, v8r)
|
|
49
|
+
* Перевіряє відповідність проєкту правилам text.mdc (oxfmt, cspell, markdownlint через bunx, v8r)
|
|
47
50
|
* @returns {Promise<number>} 0 — все OK, 1 — є проблеми
|
|
48
51
|
*/
|
|
49
52
|
export async function check() {
|
|
@@ -79,6 +82,11 @@ export async function check() {
|
|
|
79
82
|
} else {
|
|
80
83
|
fail('extensions.json: додай "DavidAnson.vscode-markdownlint" у recommendations (див. n-text.mdc)')
|
|
81
84
|
}
|
|
85
|
+
if (Array.isArray(rec) && rec.includes('oxc.oxc-vscode')) {
|
|
86
|
+
pass('extensions.json містить oxc.oxc-vscode')
|
|
87
|
+
} else {
|
|
88
|
+
fail('extensions.json: додай "oxc.oxc-vscode" у recommendations (див. n-text.mdc)')
|
|
89
|
+
}
|
|
82
90
|
} catch {
|
|
83
91
|
fail('.vscode/extensions.json — невалідний JSON')
|
|
84
92
|
}
|
|
@@ -86,6 +94,63 @@ export async function check() {
|
|
|
86
94
|
fail('.vscode/extensions.json не існує — створи з recommendations згідно n-text.mdc')
|
|
87
95
|
}
|
|
88
96
|
|
|
97
|
+
if (existsSync('.vscode/settings.json')) {
|
|
98
|
+
try {
|
|
99
|
+
const settings = JSON.parse(await readFile('.vscode/settings.json', 'utf8'))
|
|
100
|
+
if (settings['editor.formatOnSave'] === true) {
|
|
101
|
+
pass('settings.json: editor.formatOnSave увімкнено')
|
|
102
|
+
} else {
|
|
103
|
+
fail('settings.json: editor.formatOnSave має бути true')
|
|
104
|
+
}
|
|
105
|
+
const fmtTypes = ['javascript', 'typescript', 'json', 'vue', 'css', 'html']
|
|
106
|
+
for (const t of fmtTypes) {
|
|
107
|
+
const key = `[${t}]`
|
|
108
|
+
if (settings[key]?.['editor.defaultFormatter'] === 'oxc.oxc-vscode') {
|
|
109
|
+
pass(`settings.json: ${key} використовує oxc.oxc-vscode`)
|
|
110
|
+
} else {
|
|
111
|
+
fail(`settings.json: ${key} має використовувати oxc.oxc-vscode як defaultFormatter`)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
fail('.vscode/settings.json — невалідний JSON')
|
|
116
|
+
}
|
|
117
|
+
} else {
|
|
118
|
+
fail('.vscode/settings.json не існує — створи згідно n-text.mdc')
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const expectedOxfmtKeys = [
|
|
122
|
+
'arrowParens',
|
|
123
|
+
'printWidth',
|
|
124
|
+
'bracketSpacing',
|
|
125
|
+
'bracketSameLine',
|
|
126
|
+
'semi',
|
|
127
|
+
'singleQuote',
|
|
128
|
+
'tabWidth',
|
|
129
|
+
'trailingComma',
|
|
130
|
+
'useTabs'
|
|
131
|
+
]
|
|
132
|
+
if (existsSync('.oxfmtrc.json')) {
|
|
133
|
+
const cfg = JSON.parse(await readFile('.oxfmtrc.json', 'utf8'))
|
|
134
|
+
const missing = expectedOxfmtKeys.filter(k => !(k in cfg))
|
|
135
|
+
if (missing.length === 0) {
|
|
136
|
+
pass('.oxfmtrc.json містить всі обовʼязкові ключі')
|
|
137
|
+
} else {
|
|
138
|
+
fail(`.oxfmtrc.json відсутні ключі: ${missing.join(', ')}`)
|
|
139
|
+
}
|
|
140
|
+
if (cfg.semi !== false) fail('.oxfmtrc.json: semi має бути false')
|
|
141
|
+
if (cfg.singleQuote !== true) fail('.oxfmtrc.json: singleQuote має бути true')
|
|
142
|
+
if (cfg.tabWidth !== 2) fail('.oxfmtrc.json: tabWidth має бути 2')
|
|
143
|
+
if (cfg.useTabs !== false) fail('.oxfmtrc.json: useTabs має бути false')
|
|
144
|
+
if (cfg.printWidth !== 120) fail('.oxfmtrc.json: printWidth має бути 120')
|
|
145
|
+
} else {
|
|
146
|
+
fail('.oxfmtrc.json не існує — створи його')
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const prettierFiles = ['.prettierrc', '.prettierrc.json', '.prettierrc.js', 'prettier.config.js', '.prettierrc.yml']
|
|
150
|
+
for (const f of prettierFiles) {
|
|
151
|
+
if (existsSync(f)) fail(`Знайдено конфіг prettier: ${f} — видали його`)
|
|
152
|
+
}
|
|
153
|
+
|
|
89
154
|
if (existsSync('.markdownlint-cli2.jsonc')) {
|
|
90
155
|
try {
|
|
91
156
|
const ml = JSON.parse(await readFile('.markdownlint-cli2.jsonc', 'utf8'))
|
|
@@ -145,6 +210,12 @@ export async function check() {
|
|
|
145
210
|
|
|
146
211
|
if (existsSync('package.json')) {
|
|
147
212
|
const pkg = JSON.parse(await readFile('package.json', 'utf8'))
|
|
213
|
+
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
214
|
+
for (const dep of ['prettier', '@nitra/prettier-config']) {
|
|
215
|
+
if (allDeps[dep]) fail(`package.json містить залежність ${dep} — видали її`)
|
|
216
|
+
}
|
|
217
|
+
if (pkg.prettier) fail('package.json містить поле "prettier" — видали його')
|
|
218
|
+
|
|
148
219
|
const devDeps = pkg.devDependencies || {}
|
|
149
220
|
|
|
150
221
|
if (devDeps['@nitra/cspell-dict']) {
|
package/mdc/js-format.mdc
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Правила форматів JavaScript ecosystem
|
|
3
|
-
alwaysApply: true
|
|
4
|
-
version: '1.3'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
В корені проекту є файл з правилами форматування для oxfmt:
|
|
8
|
-
|
|
9
|
-
```json title=".oxfmtrc.json"
|
|
10
|
-
{
|
|
11
|
-
"arrowParens": "avoid",
|
|
12
|
-
"printWidth": 120,
|
|
13
|
-
"bracketSpacing": true,
|
|
14
|
-
"bracketSameLine": true,
|
|
15
|
-
"embeddedLanguageFormatting": "auto",
|
|
16
|
-
"endOfLine": "lf",
|
|
17
|
-
"htmlWhitespaceSensitivity": "css",
|
|
18
|
-
"insertPragma": false,
|
|
19
|
-
"jsxSingleQuote": true,
|
|
20
|
-
"proseWrap": "preserve",
|
|
21
|
-
"quoteProps": "as-needed",
|
|
22
|
-
"requirePragma": false,
|
|
23
|
-
"semi": false,
|
|
24
|
-
"singleQuote": true,
|
|
25
|
-
"tabWidth": 2,
|
|
26
|
-
"trailingComma": "none",
|
|
27
|
-
"useTabs": false,
|
|
28
|
-
"vueIndentScriptAndStyle": false
|
|
29
|
-
}
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
в файлі .vscode/extensions.json є налаштування для oxfmt:
|
|
33
|
-
|
|
34
|
-
```json title=".vscode/extensions.json"
|
|
35
|
-
{
|
|
36
|
-
"recommendations": ["oxc.oxc-vscode"]
|
|
37
|
-
}
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
в файлі .vscode/settings.json є налаштування для oxfmt:
|
|
41
|
-
|
|
42
|
-
```json title=".vscode/settings.json"
|
|
43
|
-
{
|
|
44
|
-
"editor.formatOnSave": true,
|
|
45
|
-
"[css]": {
|
|
46
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
47
|
-
},
|
|
48
|
-
"[graphql]": {
|
|
49
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
50
|
-
},
|
|
51
|
-
"[handlebars]": {
|
|
52
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
53
|
-
},
|
|
54
|
-
"[html]": {
|
|
55
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
56
|
-
},
|
|
57
|
-
"[javascript]": {
|
|
58
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
59
|
-
},
|
|
60
|
-
"[json]": {
|
|
61
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
62
|
-
},
|
|
63
|
-
"[json5]": {
|
|
64
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
65
|
-
},
|
|
66
|
-
"[jsonc]": {
|
|
67
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
68
|
-
},
|
|
69
|
-
"[less]": {
|
|
70
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
71
|
-
},
|
|
72
|
-
"[markdown]": {
|
|
73
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
74
|
-
},
|
|
75
|
-
"[mdx]": {
|
|
76
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
77
|
-
},
|
|
78
|
-
"[scss]": {
|
|
79
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
80
|
-
},
|
|
81
|
-
"[toml]": {
|
|
82
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
83
|
-
},
|
|
84
|
-
"[typescript]": {
|
|
85
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
86
|
-
},
|
|
87
|
-
"[vue]": {
|
|
88
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
89
|
-
},
|
|
90
|
-
"[yaml]": {
|
|
91
|
-
"editor.defaultFormatter": "oxc.oxc-vscode"
|
|
92
|
-
},
|
|
93
|
-
"oxc.path.oxfmt": "/opt/homebrew/bin/oxfmt"
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
Також потрібно прибрати якщо є в проекті модул @nitra/prettier-config та prettier та всі виклики prettier і налаштування для нього.
|
|
98
|
-
|
|
99
|
-
Завжди пиши JSDoc до функцій та методів.
|
|
100
|
-
|
|
101
|
-
## Перевірка
|
|
102
|
-
|
|
103
|
-
`npx @nitra/cursor check js-format`
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Перевіряє форматування коду за правилом js-format.mdc.
|
|
3
|
-
*
|
|
4
|
-
* `.oxfmtrc.json` з потрібними ключами, VSCode і oxfmt, відсутність Prettier у конфігах і залежностях.
|
|
5
|
-
*/
|
|
6
|
-
import { existsSync } from 'node:fs'
|
|
7
|
-
import { readFile } from 'node:fs/promises'
|
|
8
|
-
|
|
9
|
-
import { createCheckReporter } from './utils/check-reporter.mjs'
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Перевіряє відповідність проєкту правилам js-format.mdc
|
|
13
|
-
* @returns {Promise<number>} 0 — все OK, 1 — є проблеми
|
|
14
|
-
*/
|
|
15
|
-
export async function check() {
|
|
16
|
-
const reporter = createCheckReporter()
|
|
17
|
-
const { pass, fail } = reporter
|
|
18
|
-
|
|
19
|
-
const expectedKeys = [
|
|
20
|
-
'arrowParens',
|
|
21
|
-
'printWidth',
|
|
22
|
-
'bracketSpacing',
|
|
23
|
-
'bracketSameLine',
|
|
24
|
-
'semi',
|
|
25
|
-
'singleQuote',
|
|
26
|
-
'tabWidth',
|
|
27
|
-
'trailingComma',
|
|
28
|
-
'useTabs'
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
if (existsSync('.oxfmtrc.json')) {
|
|
32
|
-
const cfg = JSON.parse(await readFile('.oxfmtrc.json', 'utf8'))
|
|
33
|
-
const missing = expectedKeys.filter(k => !(k in cfg))
|
|
34
|
-
if (missing.length === 0) {
|
|
35
|
-
pass('.oxfmtrc.json містить всі обовʼязкові ключі')
|
|
36
|
-
} else {
|
|
37
|
-
fail(`.oxfmtrc.json відсутні ключі: ${missing.join(', ')}`)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (cfg.semi !== false) fail('.oxfmtrc.json: semi має бути false')
|
|
41
|
-
if (cfg.singleQuote !== true) fail('.oxfmtrc.json: singleQuote має бути true')
|
|
42
|
-
if (cfg.tabWidth !== 2) fail('.oxfmtrc.json: tabWidth має бути 2')
|
|
43
|
-
if (cfg.useTabs !== false) fail('.oxfmtrc.json: useTabs має бути false')
|
|
44
|
-
if (cfg.printWidth !== 120) fail('.oxfmtrc.json: printWidth має бути 120')
|
|
45
|
-
} else {
|
|
46
|
-
fail('.oxfmtrc.json не існує — створи його')
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (existsSync('.vscode/extensions.json')) {
|
|
50
|
-
const ext = JSON.parse(await readFile('.vscode/extensions.json', 'utf8'))
|
|
51
|
-
if (ext.recommendations?.includes('oxc.oxc-vscode')) {
|
|
52
|
-
pass('extensions.json містить oxc.oxc-vscode')
|
|
53
|
-
} else {
|
|
54
|
-
fail('extensions.json не містить oxc.oxc-vscode')
|
|
55
|
-
}
|
|
56
|
-
} else {
|
|
57
|
-
fail('.vscode/extensions.json не існує')
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if (existsSync('.vscode/settings.json')) {
|
|
61
|
-
const settings = JSON.parse(await readFile('.vscode/settings.json', 'utf8'))
|
|
62
|
-
if (settings['editor.formatOnSave'] === true) {
|
|
63
|
-
pass('settings.json: editor.formatOnSave увімкнено')
|
|
64
|
-
} else {
|
|
65
|
-
fail('settings.json: editor.formatOnSave має бути true')
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const fmtTypes = ['javascript', 'typescript', 'json', 'vue', 'css', 'html']
|
|
69
|
-
for (const t of fmtTypes) {
|
|
70
|
-
const key = `[${t}]`
|
|
71
|
-
if (settings[key]?.['editor.defaultFormatter'] === 'oxc.oxc-vscode') {
|
|
72
|
-
pass(`settings.json: ${key} використовує oxc.oxc-vscode`)
|
|
73
|
-
} else {
|
|
74
|
-
fail(`settings.json: ${key} має використовувати oxc.oxc-vscode як defaultFormatter`)
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
} else {
|
|
78
|
-
fail('.vscode/settings.json не існує')
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const prettierFiles = ['.prettierrc', '.prettierrc.json', '.prettierrc.js', 'prettier.config.js', '.prettierrc.yml']
|
|
82
|
-
for (const f of prettierFiles) {
|
|
83
|
-
if (existsSync(f)) fail(`Знайдено конфіг prettier: ${f} — видали його`)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
if (existsSync('package.json')) {
|
|
87
|
-
const pkg = JSON.parse(await readFile('package.json', 'utf8'))
|
|
88
|
-
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies }
|
|
89
|
-
for (const dep of ['prettier', '@nitra/prettier-config']) {
|
|
90
|
-
if (allDeps[dep]) fail(`package.json містить залежність ${dep} — видали її`)
|
|
91
|
-
}
|
|
92
|
-
if (pkg.prettier) fail('package.json містить поле "prettier" — видали його')
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return reporter.getExitCode()
|
|
96
|
-
}
|