@nitra/cursor 12.8.7 → 12.8.9
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 +12 -0
- package/package.json +1 -1
- package/rules/abie/main.mdc +9 -5
- package/rules/abie/policy/base_deployment_preem/base_deployment_preem.mdc +22 -0
- package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
- package/rules/abie/policy/health_check_policy/health_check_policy.mdc +17 -0
- package/rules/abie/policy/http_route_base/http_route_base.mdc +9 -0
- package/rules/abie/policy/package_json_shared/package_json_shared.mdc +17 -0
- package/rules/adr/main.mdc +4 -0
- package/rules/adr/policy/settings_json/settings_json.mdc +7 -0
- package/rules/adr/policy/settings_local_json/settings_local_json.mdc +7 -0
- package/rules/bun/main.mdc +3 -4
- package/rules/bun/policy/bunfig/bunfig.mdc +12 -0
- package/rules/bun/policy/package_json/package_json.mdc +14 -0
- package/rules/capacitor/main.mdc +1 -3
- package/rules/capacitor/policy/package_json/package_json.mdc +9 -0
- package/rules/ci4/main.mdc +2 -0
- package/rules/ci4/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/docker/main.mdc +1 -3
- package/rules/docker/policy/lint_docker_yml/lint_docker_yml.mdc +14 -0
- package/rules/efes/main.mdc +1 -1
- package/rules/efes/policy/package_json_shared/package_json_shared.mdc +30 -0
- package/rules/ga/main.mdc +15 -10
- package/rules/ga/policy/clean_ga_workflows/clean_ga_workflows.mdc +18 -0
- package/rules/ga/policy/clean_merged_branch/clean_merged_branch.mdc +22 -0
- package/rules/ga/policy/git_ai/git_ai.mdc +19 -0
- package/rules/ga/policy/lint_ga/lint_ga.mdc +21 -0
- package/rules/ga/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/ga/policy/vscode_settings/vscode_settings.mdc +9 -0
- package/rules/ga/policy/workflow_common/workflow_common.mdc +18 -0
- package/rules/ga/policy/zizmor_yml/zizmor_yml.mdc +9 -0
- package/rules/graphql/main.mdc +2 -0
- package/rules/graphql/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/hasura/main.mdc +1 -3
- package/rules/hasura/policy/svc_hl/svc_hl.mdc +15 -0
- package/rules/image-avif/main.mdc +1 -3
- package/rules/image-avif/policy/package_json/package_json.mdc +18 -0
- package/rules/image-compress/main.mdc +1 -1
- package/rules/image-compress/policy/package_json/package_json.mdc +13 -0
- package/rules/js/main.mdc +7 -6
- package/rules/js/policy/jscpd/jscpd.mdc +14 -0
- package/rules/js/policy/lint_js_yml/lint_js_yml.mdc +14 -0
- package/rules/js/policy/package_json/package_json.mdc +15 -0
- package/rules/js/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/js-bun-db/main.mdc +1 -6
- package/rules/js-bun-db/policy/package_json/package_json.mdc +17 -0
- package/rules/js-bun-redis/main.mdc +2 -0
- package/rules/js-bun-redis/policy/package_json/package_json.mdc +11 -0
- package/rules/js-mssql/main.mdc +1 -1
- package/rules/js-mssql/policy/package_json/package_json.mdc +9 -0
- package/rules/js-run/main.mdc +5 -3
- package/rules/js-run/policy/configmap/configmap.mdc +31 -0
- package/rules/js-run/policy/jsconfig/jsconfig.mdc +25 -0
- package/rules/js-run/policy/package_json/package_json.mdc +38 -0
- package/rules/k8s/main.mdc +21 -13
- package/rules/k8s/policy/base_kustomization/base_kustomization.mdc +12 -0
- package/rules/k8s/policy/base_manifest/base_manifest.mdc +14 -0
- package/rules/k8s/policy/gateway/gateway.mdc +17 -0
- package/rules/k8s/policy/hasura_configmap/hasura_configmap.mdc +20 -0
- package/rules/k8s/policy/hasura_httproute/hasura_httproute.mdc +16 -0
- package/rules/k8s/policy/hpa_pdb/hpa_pdb.mdc +23 -0
- package/rules/k8s/policy/kustomization/kustomization.mdc +20 -0
- package/rules/k8s/policy/manifest/manifest.mdc +17 -0
- package/rules/k8s/policy/network_policy/network_policy.mdc +22 -0
- package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
- package/rules/k8s/policy/svc_yaml/svc_yaml.mdc +12 -0
- package/rules/nginx-default-tpl/main.mdc +4 -0
- package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings.mdc +15 -0
- package/rules/npm-module/main.mdc +6 -3
- package/rules/npm-module/policy/emit_types_config/emit_types_config.mdc +40 -0
- package/rules/npm-module/policy/npm_package_json/npm_package_json.mdc +50 -0
- package/rules/npm-module/policy/root_package_json/root_package_json.mdc +37 -0
- package/rules/php/main.mdc +1 -3
- package/rules/php/policy/lint_php_yml/lint_php_yml.mdc +21 -0
- package/rules/python/main.mdc +3 -4
- package/rules/python/policy/lint_python_yml/lint_python_yml.mdc +12 -0
- package/rules/python/policy/pyproject_toml/pyproject_toml.mdc +13 -0
- package/rules/rego/main.mdc +4 -0
- package/rules/rego/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/rego/policy/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/rust/main.mdc +2 -2
- package/rules/rust/policy/lint_rust_yml/lint_rust_yml.mdc +12 -0
- package/rules/rust/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/security/main.mdc +3 -2
- package/rules/security/policy/lint_security_yml/lint_security_yml.mdc +7 -0
- package/rules/security/policy/package_json/package_json.mdc +7 -0
- package/rules/style/main.mdc +6 -5
- package/rules/style/policy/lint_style_yml/lint_style_yml.mdc +13 -0
- package/rules/style/policy/package_json/package_json.mdc +18 -0
- package/rules/style/policy/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/style/policy/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/tauri/main.mdc +1 -3
- package/rules/tauri/policy/vscode_extensions/vscode_extensions.mdc +21 -0
- package/rules/test/main.mdc +1 -3
- package/rules/test/policy/package_json/package_json.mdc +16 -0
- package/rules/text/main.mdc +13 -7
- package/rules/text/policy/cspell/cspell.mdc +34 -0
- package/rules/text/policy/lint_text/lint_text.mdc +19 -0
- package/rules/text/policy/markdownlint/markdownlint.mdc +38 -0
- package/rules/text/policy/oxfmtrc/oxfmtrc.mdc +11 -0
- package/rules/text/policy/package_json/package_json.mdc +33 -0
- package/rules/text/policy/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/text/policy/vscode_settings/vscode_settings.mdc +13 -0
- package/rules/vue/main.mdc +1 -3
- package/rules/vue/policy/package_json/package_json.mdc +30 -0
- package/scripts/lib/docs/index.md +36 -36
- package/scripts/lib/docs/rule-meta.md +10 -9
- package/scripts/lib/docs/run-lint.md +8 -8
- package/scripts/lib/rule-meta.mjs +2 -1
- package/scripts/lib/run-lint.mjs +39 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Rego-gate `.github/workflows/lint-js.yml`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_lint.lint_js_yml`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.github/workflows/lint-js.yml`.
|
|
6
|
+
|
|
7
|
+
Що перевіряється:
|
|
8
|
+
|
|
9
|
+
- Наявність усіх `uses:`-кроків з канону (subset-of по `jobs.eslint.steps`)
|
|
10
|
+
- Наявність усіх рядків `run:` з канону (substring-match по всіх кроках)
|
|
11
|
+
- `actions/checkout@v6` має мати `with.persist-credentials: false` (inverse-check)
|
|
12
|
+
- Заборона `--fix` у CI: `bunx oxlint ... --fix` або `eslint --fix` у будь-якому `run:` → deny
|
|
13
|
+
|
|
14
|
+
Канон-snippet: [lint-js.yml.snippet.yml](./template/lint-js.yml.snippet.yml)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Rego-gate `package.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_lint.package_json`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `package.json` (корінь і workspace-пакети).
|
|
6
|
+
|
|
7
|
+
Що перевіряється:
|
|
8
|
+
|
|
9
|
+
- `"type"` — точна відповідність `"module"` (з канон-snippet)
|
|
10
|
+
- `scripts.lint-js` — нормалізована точна відповідність (collapse whitespace)
|
|
11
|
+
- `engines.node` — semver-парсинг: major >= 24 (inverse, без template)
|
|
12
|
+
- `engines.bun` — semver-парсинг: >= 1.3 (inverse, без template)
|
|
13
|
+
- `devDependencies["@nitra/eslint-config"]` — наявність ключа + semver >= порогу зі snippet (`^3.10.0`); `workspace:*` завжди проходить
|
|
14
|
+
|
|
15
|
+
Канон-snippet: [package.json.snippet.json](./template/package.json.snippet.json)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Rego-gate `.vscode/extensions.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_lint.vscode_extensions`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.vscode/extensions.json`.
|
|
6
|
+
|
|
7
|
+
Що перевіряється:
|
|
8
|
+
|
|
9
|
+
- `recommendations` — subset-of: масив має містити всі три канонічні розширення (`dbaeumer.vscode-eslint`, `github.vscode-github-actions`, `oxc.oxc-vscode`)
|
|
10
|
+
|
|
11
|
+
Канон-snippet: [extensions.json.snippet.json](./template/extensions.json.snippet.json)
|
package/rules/js-bun-db/main.mdc
CHANGED
|
@@ -27,9 +27,4 @@ version: '1.15'
|
|
|
27
27
|
|
|
28
28
|
## Швидкий gate через conftest
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- `pg-format` → заміни на Bun native SQL — без ручного форматування
|
|
33
|
-
- `mysql2` → заміни на Bun native SQL
|
|
34
|
-
|
|
35
|
-
AST-скан коду (`new SQL(...)` у функціях, `unsafe()` без маркера, pg-leftover, динамічні `IN (…)` через `.join(',')`) лишається у JS-перевірці (`js/safety.mjs`). Виключення `pg` для LISTEN/NOTIFY зважується у JS (Rego не бачить JS-коду).
|
|
30
|
+
[js-bun-db-package-json](./policy/package_json/package_json.mdc)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Заборонені залежності у package.json
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_bun_db.package_json`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `**/package.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє поле `dependencies` на наявність пакетів із deny-списку [`package.json.deny.json`](./template/package.json.deny.json). Список керується даними (`--data`), тому розширюється без зміни rego-коду.
|
|
8
|
+
|
|
9
|
+
Поточний deny-список:
|
|
10
|
+
|
|
11
|
+
- `pg-format` — заміни на Bun native SQL (без ручного форматування)
|
|
12
|
+
- `mysql2` — заміни на Bun native SQL
|
|
13
|
+
|
|
14
|
+
`pg` у dependencies **не** є порушенням на рівні Rego — виняток для LISTEN/NOTIFY зважується у JS-сканері (`js/safety.mjs`).
|
|
15
|
+
|
|
16
|
+
✓ `{ "dependencies": { "pg": "^8.0.0" } }` — дозволено
|
|
17
|
+
✗ `{ "dependencies": { "pg-format": "^1.0.0" } }` — `deny: dependencies.pg-format — заміни на Bun native SQL`
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Rego gate: заборонені redis-залежності у `package.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js-bun-redis.package_json`
|
|
4
|
+
|
|
5
|
+
**Цільовий файл:** `package.json` (поле `dependencies`)
|
|
6
|
+
|
|
7
|
+
Перевіряє наявність заборонених redis-пакетів у `dependencies`. Список заборон надходить через `--data` з канонічного шаблону:
|
|
8
|
+
|
|
9
|
+
[package.json.deny.json](./template/package.json.deny.json)
|
|
10
|
+
|
|
11
|
+
Повідомлення про порушення формується як `dependencies.<pkg> — <reason>`.
|
package/rules/js-mssql/main.mdc
CHANGED
|
@@ -21,6 +21,6 @@ version: '1.4'
|
|
|
21
21
|
|
|
22
22
|
Rego-перевірки (`policy/`) — швидкий синхронний gate для одиничного `package.json` без JS-рантайму:
|
|
23
23
|
|
|
24
|
-
-
|
|
24
|
+
[js-mssql-package_json](./policy/package_json/package_json.mdc)
|
|
25
25
|
|
|
26
26
|
JS-перевірка (`deps.mjs`) — authoritative: охоплює всі `package.json` репо, AST-скан JS/TS-джерел і повний semver-triple-compare. Rego-gate — доповнення, не заміна.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## Rego-gate: версія `mssql` у `package.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js_mssql.package_json`
|
|
4
|
+
|
|
5
|
+
Цільові файли: `**/package.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє поле `dependencies.mssql` — якщо присутнє, версія має бути `>= 12.5.0`. Підтримувані формати: `^12.5.0`, `>=12.5.0`, `12.5.0`, `workspace:*` (OK). Версії нижче 12.5.x генерують `deny`.
|
|
8
|
+
|
|
9
|
+
Це швидкий синхронний gate для одиничного `package.json`. Authoritative-перевірка (повний semver-triple-compare, усі `package.json` репо) — у JS (`fix.mjs`).
|
package/rules/js-run/main.mdc
CHANGED
|
@@ -31,6 +31,8 @@ version: '1.12'
|
|
|
31
31
|
|
|
32
32
|
Rego-пакети, які запускає `npx @nitra/cursor fix js-run` / `npx @nitra/cursor check`:
|
|
33
33
|
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
-
|
|
34
|
+
[js-run-package_json](./policy/package_json/package_json.mdc)
|
|
35
|
+
|
|
36
|
+
[js-run-jsconfig](./policy/jsconfig/jsconfig.mdc)
|
|
37
|
+
|
|
38
|
+
[js-run-configmap](./policy/configmap/configmap.mdc)
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
## Rego-gate: OTEL ConfigMap (k8s)
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js-run.configmap`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `k8s/base/configmap.yaml` (і будь-які ConfigMap у kustomize-оверлеях)
|
|
6
|
+
|
|
7
|
+
**Умова спрацювання:** `input.kind == "ConfigMap"`
|
|
8
|
+
|
|
9
|
+
Перевіряє, що поле `data.OTEL_RESOURCE_ATTRIBUTES` містить усі обовʼязкові substring-маркери, визначені у template:
|
|
10
|
+
|
|
11
|
+
- `service.name=`
|
|
12
|
+
- `service.namespace=`
|
|
13
|
+
|
|
14
|
+
Канон маркерів: [configmap.yaml.contains.yml](./template/configmap.yaml.contains.yml)
|
|
15
|
+
|
|
16
|
+
**✓ Правильно**
|
|
17
|
+
|
|
18
|
+
```yaml
|
|
19
|
+
data:
|
|
20
|
+
OTEL_RESOURCE_ATTRIBUTES: 'service.name=my-svc,service.namespace=prod'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
**✗ Неправильно**
|
|
24
|
+
|
|
25
|
+
```yaml
|
|
26
|
+
data:
|
|
27
|
+
OTEL_RESOURCE_ATTRIBUTES: 'service.name=my-svc'
|
|
28
|
+
# Відсутній service.namespace= → deny
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Ресурси типу `kind: Deployment` та інші non-ConfigMap — ігноруються.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
## Rego-gate: jsconfig.json
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js-run.jsconfig`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `jsconfig.json` у корені backend workspace-пакету
|
|
6
|
+
|
|
7
|
+
Порівнює `jsconfig.json` з каноном через walker по всіх листах template:
|
|
8
|
+
|
|
9
|
+
- `compilerOptions.*` — значення мають збігатись точно
|
|
10
|
+
- `include` — масив порівнюється як множина (точний склад)
|
|
11
|
+
|
|
12
|
+
Канон: [jsconfig.json.snippet.json](./template/jsconfig.json.snippet.json)
|
|
13
|
+
|
|
14
|
+
Перевірені поля:
|
|
15
|
+
|
|
16
|
+
| Поле | Очікуване значення |
|
|
17
|
+
|------|--------------------|
|
|
18
|
+
| `compilerOptions.module` | `"NodeNext"` |
|
|
19
|
+
| `compilerOptions.moduleResolution` | `"NodeNext"` |
|
|
20
|
+
| `compilerOptions.target` | `"esnext"` |
|
|
21
|
+
| `compilerOptions.lib` | `["esnext"]` |
|
|
22
|
+
| `compilerOptions.checkJs` | `false` |
|
|
23
|
+
| `include` | `["src/**/*"]` |
|
|
24
|
+
|
|
25
|
+
Якщо розділ `compilerOptions` відсутній або не є обʼєктом — deny.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Rego-gate: package.json (залежності та scripts)
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `js-run.package_json`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `package.json` у backend workspace-пакетах (без `vite` у `devDependencies`)
|
|
6
|
+
|
|
7
|
+
Перевіряє три класи порушень за deny-списком із template:
|
|
8
|
+
|
|
9
|
+
Канон deny-списку: [package.json.deny.json](./template/package.json.deny.json)
|
|
10
|
+
|
|
11
|
+
**1. Заборонені залежності** (`dependencies` / `devDependencies`)
|
|
12
|
+
|
|
13
|
+
| Пакет | Причина |
|
|
14
|
+
|-------|---------|
|
|
15
|
+
| `bunyan` | використовуй стандартні логери |
|
|
16
|
+
| `@nitra/bunyan` | використовуй стандартні логери |
|
|
17
|
+
|
|
18
|
+
**2. Заборонений рантайм у `scripts`** (лише backend-пакети без `vite`)
|
|
19
|
+
|
|
20
|
+
- Патерн `\bnode(\s|$)` — заміни `node` на `bun`
|
|
21
|
+
- Патерн `\benv\s+\$\(cat\s+[^)]+\)\s+bun\b` — заміни `env $(cat A B) bun` на `bun --env-file=A --env-file=B`
|
|
22
|
+
|
|
23
|
+
**✓ Правильно**
|
|
24
|
+
|
|
25
|
+
```json
|
|
26
|
+
{ "scripts": { "start": "bun src/index.js" } }
|
|
27
|
+
{ "scripts": { "start": "bun --env-file=.env src/index.js" } }
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**✗ Неправильно**
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
{ "scripts": { "start": "node src/index.js" } }
|
|
34
|
+
{ "scripts": { "start": "env $(cat .env .env.local) bun src/index.js" } }
|
|
35
|
+
{ "dependencies": { "bunyan": "^1.0.0" } }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Пакети з `vite` у `devDependencies` — frontend, поза областю js-run, перевірка scripts не застосовується.
|
package/rules/k8s/main.mdc
CHANGED
|
@@ -45,16 +45,24 @@ alwaysApply: false
|
|
|
45
45
|
|
|
46
46
|
Підмножину пер-документних правил продубльовано як rego-полісі у **`npm/rules/k8s/policy/`** (запускається через **`bun run lint-rego`** для `*_test.rego` юніт-тестів і через **`npx @nitra/cursor fix k8s`** для прогону по реальних YAML). JS authoritative; rego — швидкий gate для одиничного маніфеста.
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
-
|
|
53
|
-
|
|
54
|
-
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
|
|
48
|
+
[k8s-policy-manifest](./policy/manifest/manifest.mdc)
|
|
49
|
+
|
|
50
|
+
[k8s-policy-base-manifest](./policy/base_manifest/base_manifest.mdc)
|
|
51
|
+
|
|
52
|
+
[k8s-policy-base-kustomization](./policy/base_kustomization/base_kustomization.mdc)
|
|
53
|
+
|
|
54
|
+
[k8s-policy-gateway](./policy/gateway/gateway.mdc)
|
|
55
|
+
|
|
56
|
+
[k8s-policy-hasura-configmap](./policy/hasura_configmap/hasura_configmap.mdc)
|
|
57
|
+
|
|
58
|
+
[k8s-policy-hasura-httproute](./policy/hasura_httproute/hasura_httproute.mdc)
|
|
59
|
+
|
|
60
|
+
[k8s-policy-hpa-pdb](./policy/hpa_pdb/hpa_pdb.mdc)
|
|
61
|
+
|
|
62
|
+
[k8s-policy-kustomization](./policy/kustomization/kustomization.mdc)
|
|
63
|
+
|
|
64
|
+
[k8s-policy-network-policy](./policy/network_policy/network_policy.mdc)
|
|
65
|
+
|
|
66
|
+
[k8s-policy-svc-yaml](./policy/svc_yaml/svc_yaml.mdc)
|
|
67
|
+
|
|
68
|
+
[k8s-policy-svc-hl-yaml](./policy/svc_hl_yaml/svc_hl_yaml.mdc)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Перевірки `base/kustomization.yaml`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.base_kustomization`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `k8s/.../base/kustomization.yaml` (вибір через `isBaseKustomizationPath` у JS; `kind: Kustomization`, `apiVersion: kustomize.config.k8s.io/…`).
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `namespace:` — обов'язковий і непорожній (наприклад `namespace: dev`)
|
|
10
|
+
- `resources:` — не повинен містити `hpa.yaml` або `pdb.yaml` (у будь-якому підкаталозі); HPA/PDB мають бути у sibling-каталозі `components/` і підключатися з overlay через `components: [- ../components]`
|
|
11
|
+
|
|
12
|
+
**Примітка:** рекурсивний обхід `resources:`/`components:`/`bases:` із зануренням у вкладені `kustomization.yaml` — у JS (`verifyK8sBaseKustomizeHasNoHpaPdb`). NetworkPolicy у `base/resources:` — дозволена і не блокується цим правилом.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
## Перевірки маніфестів у шарі `base/`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.base_manifest`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** будь-який `*.yaml` у шляху `k8s/.../base/` (окрім `kustomization.yaml`). JS відбирає файли через `isK8sBaseManifestYamlPath` і передає conftest з цим namespace.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- Namespaced kind — обов'язковий непорожній `metadata.namespace` (cluster-scoped kinds, `List`, `Kustomization` — виняток; список cluster-scoped kinds узгоджено з `CLUSTER_SCOPED_KINDS` у `fix.mjs`)
|
|
10
|
+
- `kind: Deployment` — фіксовані resource-requests у кожному контейнері (включно з `initContainers`):
|
|
11
|
+
- `resources.requests.cpu` рівно `"0.02"` (або число `0.02`)
|
|
12
|
+
- `resources.requests.memory` рівно `"128Mi"` (суфікс `Mi` без урахування регістру)
|
|
13
|
+
|
|
14
|
+
**Примітка:** cross-file перевірки (`metadataNamespaceRequiredViolation` у ширшому контексті дерева) лишаються у JS.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Перевірки Gateway API маршрутів і HealthCheckPolicy
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.gateway`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** YAML з `kind` одного з: `HTTPRoute`, `GRPCRoute`, `TCPRoute`, `TLSRoute`, `UDPRoute` (`apiVersion: gateway.networking.k8s.io/…`); `HealthCheckPolicy` (`apiVersion: networking.gke.io/…`).
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `HealthCheckPolicy`: `spec.targetRef` обов'язковий; якщо `targetRef.kind` не вказано або `Service` — `targetRef.name` має закінчуватися на `-hl` (headless Service)
|
|
10
|
+
- Gateway API маршрут: кожен `backendRef` до Service (визначається за полями `name` + `port`; `kind`/`group` необов'язкові) — ім'я має закінчуватися на `-hl`
|
|
11
|
+
- Gateway API маршрут: `backendRef` з полем `namespace`, що збігається з `metadata.namespace` маршруту, — заборонено (надлишкове поле, ламається при overlay-перенесеннях)
|
|
12
|
+
|
|
13
|
+
**Приклади:**
|
|
14
|
+
|
|
15
|
+
✓ `backendRef.name: my-svc-hl` (headless)
|
|
16
|
+
✗ `backendRef.name: my-svc` (без суфікса `-hl`)
|
|
17
|
+
✗ `backendRef.namespace: dev` при `metadata.namespace: dev` (redundant)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Перевірки ConfigMap для Hasura-Deployment
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.hasura_configmap`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `configmap.yaml` у каталогах, де є Deployment з образом `hasura/graphql-engine`. JS (`manifests.mjs`) знаходить відповідні ConfigMap через cross-file збіг і передає їх conftest з цим namespace.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється (обов'язкові ключі у `data`):**
|
|
8
|
+
|
|
9
|
+
| Ключ | Очікуване значення |
|
|
10
|
+
|------|--------------------|
|
|
11
|
+
| `HASURA_GRAPHQL_ENABLE_REMOTE_SCHEMA_PERMISSIONS` | `"true"` |
|
|
12
|
+
| `HASURA_GRAPHQL_ENABLE_RELAY` | `"false"` |
|
|
13
|
+
| `HASURA_GRAPHQL_ENABLE_TELEMETRY` | `"false"` |
|
|
14
|
+
| `HASURA_GRAPHQL_ENABLED_LOG_TYPES` | `"startup,http-log"` (точно) |
|
|
15
|
+
| `HASURA_GRAPHQL_ENABLED_APIS` | `"metadata,graphql,pgdump"` (base/dev; overlay має патчем замінити на `"metadata,graphql"`) |
|
|
16
|
+
| `HASURA_GRAPHQL_DISABLE_EVENTING` | ключ обов'язковий, значення довільне (рекомендовано `"true"`) |
|
|
17
|
+
|
|
18
|
+
Семантика: `"true"`/`"false"` приймаються як boolean або рядок (case-insensitive); точний рядок — exact match.
|
|
19
|
+
|
|
20
|
+
**Примітка:** відбір ConfigMap за сусідством із Hasura-Deployment — cross-file, у JS. Rego — пер-документна валідація полів `data`.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Перевірки HTTPRoute, парного з Hasura-Deployment
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.hasura_httproute`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `hr.yaml` (або будь-який HTTPRoute з `kind: HTTPRoute`) у каталогах, де є Deployment з образом `hasura/graphql-engine`. JS знаходить пару Deployment–HTTPRoute через `collectHasuraDeploymentsAndHttpRoutes` і передає conftest з цим namespace.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється — канон 4 правил у `spec.rules` (у порядку):**
|
|
8
|
+
|
|
9
|
+
1. `matches: [{path: {type: Exact, value: "<prefix>/ql"}}]` (без headers) + `filters: [RequestRedirect ReplaceFullPath "<prefix>/ql/console" statusCode 302]`
|
|
10
|
+
2. `matches: [{path: {type: Exact, value: "<prefix>/ql/"}}]` + такий самий redirect на `<prefix>/ql/console`
|
|
11
|
+
3. `matches: [{path: {type: PathPrefix, value: "<prefix>/ql"}}]` + `filters: [URLRewrite ReplacePrefixMatch "/"]` + один `backendRef` на headless Service
|
|
12
|
+
4. WebSocket: `matches: [{path: PathPrefix "<prefix>/ql", headers: [{Exact "Upgrade: websocket"}]}]` + `filters: [URLRewrite ReplacePrefixMatch "/", RequestHeaderModifier remove [Authorization]]` + той самий `backendRef`
|
|
13
|
+
|
|
14
|
+
`<prefix>` визначається автоматично як рядок до `/ql` у першому matching-правилі. Додаткові правила поверх канону дозволені.
|
|
15
|
+
|
|
16
|
+
**Примітка:** cross-file прив'язка HTTPRoute до Deployment — JS (`validateHasuraHttpRouteCanon`).
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
## Структурні перевірки HPA і PDB
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.hpa_pdb`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `hpa.yaml` (`kind: HorizontalPodAutoscaler`) та `pdb.yaml` (`kind: PodDisruptionBudget`) у overlay-каталогах (не в `base/`).
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
HPA (`kind: HorizontalPodAutoscaler` або `apiVersion: autoscaling/…`):
|
|
10
|
+
- `apiVersion: autoscaling/v2` (не v1)
|
|
11
|
+
- `kind: HorizontalPodAutoscaler`
|
|
12
|
+
- `spec` — присутній об'єкт
|
|
13
|
+
- `spec.behavior` — присутній; містить `scaleUp` і `scaleDown`, кожен з непорожнім масивом `policies`
|
|
14
|
+
- `spec.metrics` — непорожній масив
|
|
15
|
+
|
|
16
|
+
PDB (`kind: PodDisruptionBudget` або `apiVersion: policy/v1`):
|
|
17
|
+
- `apiVersion: policy/v1`
|
|
18
|
+
- `kind: PodDisruptionBudget`
|
|
19
|
+
- `spec` — присутній об'єкт
|
|
20
|
+
- `spec.selector` — присутній об'єкт
|
|
21
|
+
- `spec.selector.matchLabels` — присутній об'єкт
|
|
22
|
+
|
|
23
|
+
**Примітка:** cross-file перевірки (відповідність `expectedDeployName`, `expectedAppLabel`, `isDevLike`-сегмент) лишаються у JS (`hpaManifestViolations`, `pdbManifestViolations`).
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Структурні перевірки `kustomization.yaml`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.kustomization`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** будь-який `kustomization.yaml` (`kind: Kustomization`, `apiVersion: kustomize.config.k8s.io/…`).
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `resources[]` — має бути масивом рядків; непорожні рядки мають бути відсортовані за алфавітом (en, case-insensitive)
|
|
10
|
+
- `patches[]` — має бути масивом; елементи мають бути відсортовані за tuple `(target.kind, target.name, target.namespace, path)` (case-insensitive)
|
|
11
|
+
- Inline patch (поле `patch` як YAML-рядок JSON6902): у наборі операцій не може бути одночасно `op: remove` і `op: add` на той самий `path` — потрібен `op: replace`
|
|
12
|
+
|
|
13
|
+
**Приклади:**
|
|
14
|
+
|
|
15
|
+
✓ `resources: [deployment.yaml, hpa.yaml, svc.yaml]` (алфавіт)
|
|
16
|
+
✗ `resources: [svc.yaml, deployment.yaml]` (не за алфавітом)
|
|
17
|
+
✓ `op: replace` для зміни значення поля
|
|
18
|
+
✗ `op: remove` + `op: add` на один `path` в одному patch
|
|
19
|
+
|
|
20
|
+
**Примітка:** резолюція kustomize-дерева, перевірка існування refs на диску, парність `svc.yaml`/`svc-hl.yaml` — JS (`rules/k8s/fix.mjs`).
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Пер-документні перевірки маніфестів Kubernetes
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.manifest`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** будь-який `*.yaml` у шляху з `k8s/` (окрім `kustomization.yaml`, `base/`, `svc.yaml`, `svc-hl.yaml`). Conftest розрізає multi-doc YAML по `---` і запускає policy на кожен документ окремо.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `kind: Ingress` — заборонено; потрібен Gateway API (HTTPRoute / HealthCheckPolicy)
|
|
10
|
+
- `apiVersion: autoscaling/v1` — заборонено; потрібен `autoscaling/v2`
|
|
11
|
+
- `kind: Service` — анотації `cloud.google.com/neg` та `cloud.google.com/backend-config` заборонені
|
|
12
|
+
- `kind: Deployment` — у кожного контейнера (включно з `initContainers`) обов'язкові `resources.requests.cpu` і `resources.requests.memory` (непорожній рядок або число > 0)
|
|
13
|
+
- `kind: Deployment` з образом `hasura/graphql-engine` — образ має бути у білому списку `allowed_hasura_images` (зараз: `hasura/graphql-engine:v2.49.2.ubuntu.amd64`; `docker.io/` префікс допустимий; digest `@sha256:…` відрізається перед порівнянням)
|
|
14
|
+
- `kind: Deployment` — `spec.strategy.type: RollingUpdate` з `maxUnavailable: 0` і `maxSurge: 1`
|
|
15
|
+
- `kind: Deployment` — канонічний запис у `spec.template.spec.topologySpreadConstraints`: `maxSkew: 1`, `topologyKey: kubernetes.io/hostname`, `whenUnsatisfiable: ScheduleAnyway`, `labelSelector.matchLabels.app: <app-label>` (перевіряється лише для Deployment з міткою `app` у `spec.selector.matchLabels`)
|
|
16
|
+
|
|
17
|
+
**Примітка:** cross-file логіка (Kustomize-резолюція, парність svc/svc-hl, HPA/PDB за каталогом, schema modeline) лишається у JS `rules/k8s/fix.mjs`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Перевірки NetworkPolicy
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.network_policy`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** `networkpolicy.yaml` / будь-який YAML з `kind: NetworkPolicy` або `apiVersion: networking.k8s.io/…`.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `apiVersion: networking.k8s.io/v1`
|
|
10
|
+
- `kind: NetworkPolicy`
|
|
11
|
+
- `spec` — присутній об'єкт
|
|
12
|
+
- `spec.podSelector.matchLabels` — присутній об'єкт; поле `app` обов'язкове і непорожнє
|
|
13
|
+
- `spec.policyTypes` — містить `Ingress` і `Egress`
|
|
14
|
+
- `spec.ingress` — хоча б одне правило з `from.podSelector`
|
|
15
|
+
- **Superset-перевірка egress/ingress:** кожне правило з канон-сніпета має бути присутнє в `spec.egress` / `spec.ingress` (extra-правила дозволені). Канон обирається за анотацією `nitra.dev/workload-kind`:
|
|
16
|
+
- `StatefulSet` → [stateful-set.snippet.yaml](./template/stateful-set.snippet.yaml) (додає intra-replica ingress/egress)
|
|
17
|
+
- решта (default) → [deployment.snippet.yaml](./template/deployment.snippet.yaml)
|
|
18
|
+
- Заборонено `egress: [{}]` (allow-all) — навіть як extra-правило
|
|
19
|
+
|
|
20
|
+
**Передача snippets:** через `--data` при виклику conftest (JS передає `templateData` для `runConftestBatch`).
|
|
21
|
+
|
|
22
|
+
**Примітка:** cross-file визначення `metadata.name` воркнавантаження і мітки `app` — JS (`validateNetworkPolicyForWorkload`).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## Перевірки `svc-hl.yaml` (Headless Service)
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.svc_hl_yaml`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** лише `svc-hl.yaml` (basename). JS відбирає файли через walk по `basename == "svc-hl.yaml"`.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `kind: Service` — `metadata.name` має закінчуватися на `-hl`
|
|
10
|
+
- `kind: Service` — `spec.clusterIP` має бути `None` (headless)
|
|
11
|
+
|
|
12
|
+
✓ `metadata.name: my-app-hl`, `spec.clusterIP: None`
|
|
13
|
+
✗ `metadata.name: my-app` (без суфікса), `spec.clusterIP: 10.0.0.1`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
## Перевірки `svc.yaml` (ClusterIP Service)
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `k8s.svc_yaml`
|
|
4
|
+
|
|
5
|
+
**Цільові файли:** лише `svc.yaml` (basename). JS відбирає файли через walk по `basename == "svc.yaml"` і передає conftest з цим namespace.
|
|
6
|
+
|
|
7
|
+
**Що перевіряється:**
|
|
8
|
+
|
|
9
|
+
- `kind: Service` — `spec.type` має бути `ClusterIP` (відсутній `spec` або `type != "ClusterIP"` — порушення)
|
|
10
|
+
|
|
11
|
+
✓ `spec.type: ClusterIP`
|
|
12
|
+
✗ `spec.type: LoadBalancer` або відсутній `spec`
|
|
@@ -16,3 +16,7 @@ alwaysApply: false
|
|
|
16
16
|
[nginx-default-tpl-ini-keys](./js/ini-keys.mdc)
|
|
17
17
|
|
|
18
18
|
[nginx-default-tpl-vscode](./js/vscode.mdc)
|
|
19
|
+
|
|
20
|
+
[nginx-default-tpl-vscode_extensions](./policy/vscode_extensions/vscode_extensions.mdc)
|
|
21
|
+
|
|
22
|
+
[nginx-default-tpl-vscode_settings](./policy/vscode_settings/vscode_settings.mdc)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Rego-gate: наявність розширення nginx у `.vscode/extensions.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `nginx_default_tpl.vscode_extensions`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.vscode/extensions.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє, що масив `recommendations` містить рядок `"ahmadalli.vscode-nginx-conf"`. Відсутнє поле `recommendations` або порожній масив — теж deny.
|
|
8
|
+
|
|
9
|
+
✓ `{"recommendations": ["ahmadalli.vscode-nginx-conf"]}`
|
|
10
|
+
✗ `{"recommendations": []}` — розширення відсутнє
|
|
11
|
+
✗ `{}` — поле `recommendations` відсутнє
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Rego-gate: налаштування форматера nginx у `.vscode/settings.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `nginx_default_tpl.vscode_settings`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.vscode/settings.json`
|
|
6
|
+
|
|
7
|
+
Три незалежні deny-правила:
|
|
8
|
+
|
|
9
|
+
1. `"editor.formatOnSave"` має бути `true` (відсутність або `false` → deny).
|
|
10
|
+
2. `"[nginx]"` має бути обʼєктом (рядок або відсутність → deny).
|
|
11
|
+
3. `"[nginx].editor.defaultFormatter"` має дорівнювати `"ahmadalli.vscode-nginx-conf"`.
|
|
12
|
+
|
|
13
|
+
✓ `{"editor.formatOnSave": true, "[nginx]": {"editor.defaultFormatter": "ahmadalli.vscode-nginx-conf"}}`
|
|
14
|
+
✗ `{"editor.formatOnSave": false, "[nginx]": {"editor.defaultFormatter": "ahmadalli.vscode-nginx-conf"}}` — formatOnSave не true
|
|
15
|
+
✗ `{"editor.formatOnSave": true, "[nginx]": "ahmadalli.vscode-nginx-conf"}` — `[nginx]` не обʼєкт
|
|
@@ -25,7 +25,10 @@ Bun monorepo: workspace **`npm/`**, кореневий **`package.json`**, **`.g
|
|
|
25
25
|
|
|
26
26
|
Rego-пакети (запускаються через `npx @nitra/cursor fix`):
|
|
27
27
|
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
-
|
|
28
|
+
[npm-module-npm_package_json](./policy/npm_package_json/npm_package_json.mdc)
|
|
29
|
+
|
|
30
|
+
[npm-module-root_package_json](./policy/root_package_json/root_package_json.mdc)
|
|
31
|
+
|
|
32
|
+
[npm-module-emit_types_config](./policy/emit_types_config/emit_types_config.mdc)
|
|
33
|
+
|
|
31
34
|
- `npm_module.npm_publish_yml` — template-driven перевірка `.github/workflows/npm-publish.yml` (deep-subset: усі обовʼязкові поля й кроки з канонічного сніпету).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
## Rego-gate: конфігурація генерації типів `npm/tsconfig.emit-types.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `npm-module.emit_types_config`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `npm/tsconfig.emit-types.json`
|
|
6
|
+
|
|
7
|
+
### Що перевіряється
|
|
8
|
+
|
|
9
|
+
Leaf-by-leaf порівняння з канонічним сніпетом (через `--data`): кожне поле всередині `compilerOptions` має точно відповідати очікуваному значенню. Якщо секція `compilerOptions` відсутня або не є обʼєктом — окрема deny-помилка.
|
|
10
|
+
|
|
11
|
+
Канонічний сніпет: [tsconfig.emit-types.json.snippet.json](./template/tsconfig.emit-types.json.snippet.json)
|
|
12
|
+
|
|
13
|
+
### Допустимі відхилення
|
|
14
|
+
|
|
15
|
+
Додаткові поля у `compilerOptions` (наприклад `rootDir`, `baseUrl`) не спричиняють помилку — перевіряється лише наявність і коректність обовʼязкових ключів зі сніпету.
|
|
16
|
+
|
|
17
|
+
### Приклади
|
|
18
|
+
|
|
19
|
+
✓ Правильно:
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"compilerOptions": {
|
|
23
|
+
"allowJs": true,
|
|
24
|
+
"declaration": true,
|
|
25
|
+
"emitDeclarationOnly": true,
|
|
26
|
+
"outDir": "types",
|
|
27
|
+
"skipLibCheck": true
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
✗ Неправильно — неправильний `outDir`:
|
|
33
|
+
```json
|
|
34
|
+
{ "compilerOptions": { "outDir": "dist" } }
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
✗ Неправильно — відсутній `compilerOptions`:
|
|
38
|
+
```json
|
|
39
|
+
{}
|
|
40
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
## Rego-gate: валідація `npm/package.json`
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `npm-module.npm_package_json`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `npm/package.json`
|
|
6
|
+
|
|
7
|
+
### Що перевіряється
|
|
8
|
+
|
|
9
|
+
**Поле `types`** (логіка в rego, не template-driven):
|
|
10
|
+
- Має відповідати патерну `./types/index.d.ts` або `./types/<назва>.d.ts|.d.mts`.
|
|
11
|
+
- Шляхи поза директорією `types/` або з іншими розширеннями (`.ts` без `.d`) — deny.
|
|
12
|
+
|
|
13
|
+
**Поле `files`** (частково template-driven):
|
|
14
|
+
- Обовʼязкове, має бути непорожнім масивом.
|
|
15
|
+
- Subset-of перевірка: кожне значення з канонічного сніпету має бути присутнє у `files`. За замовчуванням — `"types"` обовʼязковий.
|
|
16
|
+
|
|
17
|
+
**Поле `devDependencies`** (inverse-pattern, логіка в rego):
|
|
18
|
+
- Не публікуються користувачам пакета — має бути відсутнє або порожнє `{}`.
|
|
19
|
+
- Наявність будь-яких devDeps → deny з переліком залежностей. Перенести у кореневий `package.json`.
|
|
20
|
+
|
|
21
|
+
Канонічний сніпет `files`: [package.json.snippet.json](./template/package.json.snippet.json)
|
|
22
|
+
|
|
23
|
+
FS-перевірки (наявність файлу зі шляху `types`, скан tarball на тест-патерни) — у JS-перевірці, не тут.
|
|
24
|
+
|
|
25
|
+
### Приклади
|
|
26
|
+
|
|
27
|
+
✓ Правильно:
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"name": "@nitra/cursor",
|
|
31
|
+
"types": "./types/bin/n-cursor.d.ts",
|
|
32
|
+
"files": ["types", "mdc", "bin", "CHANGELOG.md"],
|
|
33
|
+
"dependencies": { "oxc-parser": "^0.128.0" }
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
✗ Неправильно — `types` поза директорією `types/`:
|
|
38
|
+
```json
|
|
39
|
+
{ "types": "./dist/index.d.ts" }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
✗ Неправильно — `files` без `"types"`:
|
|
43
|
+
```json
|
|
44
|
+
{ "files": ["bin", "mdc"] }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
✗ Неправильно — наявні `devDependencies`:
|
|
48
|
+
```json
|
|
49
|
+
{ "devDependencies": { "@nitra/cursor": "^1.0.0" } }
|
|
50
|
+
```
|