@nitra/cursor 5.3.4 → 5.4.0
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/.claude-template/settings.template.json +2 -2
- package/.pi-template/extensions/n-cursor-adr/docs/index.md +13 -24
- package/CHANGELOG.md +11 -0
- package/bin/n-cursor.js +43 -22
- package/lib/docs/models.md +29 -18
- package/lib/docs/omlx-trace.md +51 -0
- package/lib/docs/omlx.md +31 -15
- package/lib/omlx.mjs +2 -5
- package/package.json +1 -1
- package/rules/abie/docs/fix.md +17 -11
- package/rules/adr/docs/fix.md +25 -140
- package/rules/bun/docs/fix.md +18 -151
- package/rules/capacitor/docs/fix.md +16 -13
- package/rules/capacitor/js/docs/platforms.md +31 -43
- package/rules/changelog/docs/fix.md +25 -169
- package/rules/ci4/docs/fix.md +11 -14
- package/rules/doc-files/doc-files.mdc +60 -0
- package/rules/doc-files/docs/fix.md +31 -0
- package/rules/doc-files/fix.mjs +19 -0
- package/{skills → rules}/doc-files/js/docgen-extract.mjs +42 -19
- package/{skills → rules}/doc-files/js/docgen-ignore.mjs +2 -1
- package/{skills → rules}/doc-files/js/docgen-scan.mjs +9 -1
- package/{skills → rules}/doc-files/js/docs/docgen-crc.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-extract-anchors.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-extract.md +2 -2
- package/{skills → rules}/doc-files/js/docs/docgen-files-batch.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-gen.md +1 -1
- package/{skills → rules}/doc-files/js/docs/docgen-ignore.md +4 -4
- package/rules/doc-files/js/docs/docgen-prompts.md +39 -0
- package/rules/doc-files/js/docs/docgen-scan.md +54 -0
- package/rules/doc-files/js/docs/lint.md +36 -0
- package/rules/doc-files/js/docs/units-js.md +31 -0
- package/rules/doc-files/js/docs/units-rs.md +35 -0
- package/rules/doc-files/js/docs/units.md +30 -0
- package/rules/doc-files/js/lint.mjs +96 -0
- package/{skills → rules}/doc-files/js/units-rs.mjs +37 -17
- package/rules/doc-files/lint/docs/lint.md +37 -0
- package/rules/doc-files/lint/lint.mjs +105 -0
- package/rules/doc-files/meta.json +1 -0
- package/rules/docker/docs/fix.md +21 -161
- package/rules/efes/docs/fix.md +23 -194
- package/rules/feedback/docs/fix.md +10 -8
- package/rules/ga/docs/fix.md +10 -5
- package/rules/graphql/docs/fix.md +23 -119
- package/rules/hasura/docs/fix.md +19 -5
- package/rules/hasura/js/docs/internal_urls.md +34 -307
- package/rules/image-avif/docs/fix.md +16 -127
- package/rules/image-compress/docs/fix.md +20 -141
- package/rules/image-compress/js/docs/package_setup.md +22 -182
- package/rules/js-bun-db/docs/fix.md +23 -139
- package/rules/js-bun-db/js/docs/safety.md +33 -221
- package/rules/js-bun-redis/docs/fix.md +25 -114
- package/rules/js-bun-redis/js/docs/imports.md +18 -166
- package/rules/js-lint/docs/fix.md +30 -108
- package/rules/js-lint/js/docs/lint-findings.md +37 -17
- package/rules/js-lint/js/docs/lint.md +22 -238
- package/rules/js-lint/js/docs/tooling.md +34 -331
- package/rules/js-lint-ci/docs/fix.md +16 -149
- package/rules/js-lint-ci/js/docs/lint.md +16 -136
- package/rules/js-mssql/docs/fix.md +18 -123
- package/rules/js-mssql/js/docs/deps.md +28 -251
- package/rules/js-run/docs/fix.md +23 -138
- package/rules/js-run/js/docs/runtime.md +24 -378
- package/rules/k8s/docs/fix.md +18 -123
- package/rules/nginx-default-tpl/docs/fix.md +22 -118
- package/rules/nginx-default-tpl/js/docs/template.md +38 -360
- package/rules/npm-module/docs/fix.md +27 -89
- package/rules/npm-module/js/docs/header_doc_pointer.md +15 -15
- package/rules/npm-module/js/docs/package_structure.md +36 -258
- package/rules/npm-module/js/docs/rule_meta.md +25 -127
- package/rules/npm-module/js/docs/skill_meta.md +18 -180
- package/rules/php/docs/fix.md +21 -98
- package/rules/php/js/docs/tooling.md +20 -143
- package/rules/python/docs/fix.md +25 -157
- package/rules/python/js/docs/applies.md +20 -98
- package/rules/python/js/docs/tooling.md +27 -144
- package/rules/rego/docs/fix.md +24 -112
- package/rules/rego/js/docs/applies.md +20 -164
- package/rules/rego/js/docs/lint.md +15 -110
- package/rules/release/docs/fix.md +16 -114
- package/rules/rust/docs/fix.md +24 -119
- package/rules/rust/js/docs/applies.md +20 -129
- package/rules/security/docs/fix.md +21 -78
- package/rules/security/js/docs/sample_secret.md +23 -182
- package/rules/security/js/docs/trufflehog.md +19 -128
- package/rules/style-lint/docs/fix.md +16 -150
- package/rules/style-lint/js/docs/lint.md +21 -172
- package/rules/style-lint/js/docs/tooling.md +19 -184
- package/rules/tauri/docs/fix.md +26 -152
- package/rules/tauri/js/docs/cargo_mutants_config.md +21 -159
- package/rules/tauri/js/docs/tooling.md +20 -217
- package/rules/test/docs/fix.md +19 -127
- package/rules/test/js/data/stryker_config/docs/stryker.config.baseline.md +15 -127
- package/rules/test/js/data/stryker_config/docs/stryker.config.vue.baseline.md +17 -153
- package/rules/test/js/docs/cargo_mutants_config.md +24 -164
- package/rules/test/js/docs/location.md +24 -126
- package/rules/test/js/docs/no-process-chdir.md +20 -151
- package/rules/test/js/docs/no-relative-fs-path.md +24 -261
- package/rules/test/js/docs/stryker_config.md +48 -148
- package/rules/test/js/docs/vitest-config-pool-forks.md +21 -164
- package/rules/text/docs/fix.md +25 -113
- package/rules/text/js/docs/forbidden-prettier.md +21 -132
- package/rules/text/js/docs/formatting.md +60 -251
- package/rules/text/js/docs/lint.md +17 -114
- package/rules/vue/docs/fix.md +25 -118
- package/rules/vue/js/docs/packages.md +25 -323
- package/rules/worktree/docs/fix.md +31 -150
- package/scripts/coverage-classify/docs/index.md +23 -209
- package/scripts/coverage-classify/docs/verdict-schema.md +14 -159
- package/scripts/dispatcher/docs/trace.md +35 -0
- package/scripts/docs/auto-rules.md +37 -361
- package/scripts/docs/lint-cli.md +12 -13
- package/scripts/docs/post-tool-use-fix.md +16 -15
- package/scripts/docs/skills-cli.md +26 -23
- package/scripts/docs/sync-claude-config.md +94 -34
- package/scripts/docs/worktree-cli.md +11 -34
- package/scripts/lib/docs/assert-project-root.md +14 -16
- package/scripts/lib/docs/changed-files.md +24 -139
- package/scripts/lib/docs/discover-check-rules-from-cursor.md +14 -146
- package/scripts/lib/docs/rule-predicates.md +20 -17
- package/scripts/lib/docs/run-rule-cli.md +14 -18
- package/scripts/lib/docs/run-rule.md +13 -20
- package/scripts/lib/docs/run-standard-rule.md +12 -15
- package/scripts/lib/docs/sync-gitignore-worktree.md +15 -18
- package/scripts/lib/rule-predicates.mjs +1 -1
- package/scripts/sync-claude-config.mjs +4 -1
- package/scripts/utils/docs/with-lock.md +19 -12
- package/scripts/utils/with-lock.mjs +4 -2
- package/skills/doc-aggregate/SKILL.md +2 -2
- package/skills/doc-aggregate/js/docgen-ignore.mjs +6 -6
- package/skills/doc-aggregate/js/docs/docgen-ignore.md +1 -1
- package/skills/doc-aggregate/js/docs/docgen-scan.md +78 -0
- package/skills/doc-files/.changes/260612-0031.md +5 -0
- package/skills/doc-files/.changes/260612-0036.md +5 -0
- package/skills/doc-files/.changes/260612-0114.md +5 -0
- package/skills/doc-files/SKILL.md +6 -6
- package/skills/fix/js/docs/llm-worker.md +17 -15
- package/skills/fix/js/docs/orchestrator.md +30 -23
- package/skills/fix/js/docs/t0.md +26 -16
- package/skills/start-check/js/docs/check.md +26 -22
- package/skills/taze/js/docs/diff.md +44 -20
- package/skills/doc-files/js/docs/docgen-prompts.md +0 -32
- package/skills/doc-files/js/docs/docgen-scan.md +0 -25
- package/skills/doc-files/js/docs/units-rs.md +0 -35
- /package/{skills → rules}/doc-files/js/docgen-crc.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-extract-anchors.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-files-batch.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-gen.mjs +0 -0
- /package/{skills → rules}/doc-files/js/docgen-prompts.mjs +0 -0
- /package/{skills → rules}/doc-files/js/units-js.mjs +0 -0
- /package/{skills → rules}/doc-files/js/units.mjs +0 -0
|
@@ -1,133 +1,37 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/rules/nginx-default-tpl/fix.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 38cf876b
|
|
5
|
+
score: 100
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
+
# fix.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Виконує застосування політики безпеки до посилань mdc.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. **Standalone mode** — якщо файл запущено напряму через `bun rules/nginx-default-tpl/fix.mjs`, то відпрацьовує повний CLI-цикл (завантаження конфігурації, whitelist, summary) і завершує процес з відповідним exit-кодом для CI/IDE.
|
|
14
|
+
Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`, включаючи завантаження конфігурації, перевірку дозволених елементів та підбиття підсумку.
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
## Поведінка
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
1. Запуск правила.
|
|
19
|
+
* Приймає контекст прогону.
|
|
20
|
+
* Виконує застосування JS-занепокоєних до політики до посилань mdc.
|
|
21
|
+
* Повертає результат.
|
|
22
|
+
2. Запуск правила у режимі CLI.
|
|
23
|
+
* Викликається через оркестрацію CLI.
|
|
24
|
+
* Виконує повний еквівалент команди `npx @nitra/cursor fix <id>`.
|
|
25
|
+
* Виконує завантаження конфігурації, перевірку дозволених елементів та підбиття підсумку.
|
|
26
|
+
* Встановлює код виходу процесу на основі результату.
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
| ------- | --------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
22
|
-
| `run` | `function(ctx?): Promise<number>` | Library-API: виконує стандартний пайплайн правила; повертає exit-код (0 — OK, 1 — порушення). |
|
|
28
|
+
## Публічний API
|
|
23
29
|
|
|
24
|
-
|
|
30
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
31
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
25
32
|
|
|
26
|
-
##
|
|
33
|
+
## Гарантії поведінки
|
|
27
34
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
33
|
-
*/
|
|
34
|
-
export function run(ctx) {
|
|
35
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
36
|
-
}
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
- **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`
|
|
40
|
-
- **Параметри:**
|
|
41
|
-
- `ctx` _(необов’язковий)_ — об’єкт контексту прогону типу `RuleContext` з `../../scripts/lib/run-standard-rule.mjs`. Зазвичай містить кеші (наприклад, `walkCache` — спільний результат обходу файлової системи між кількома правилами), щоб не повторювати дорогі операції під час batch-прогону. Якщо `ctx` не передано — `runStandardRule` створює власне ізольоване оточення.
|
|
42
|
-
- **Повертає:** `Promise<number>`
|
|
43
|
-
- `0` — правило не знайшло порушень (або всі порушення були автоматично виправлені).
|
|
44
|
-
- `1` — правило знайшло порушення, які потрібно ескалувати у CI / IDE.
|
|
45
|
-
- **Side effects:**
|
|
46
|
-
- Запускає стандартний пайплайн `runStandardRule`, який залежно від реалізації може **читати файли** проєкту, **писати fix-патчі**, **друкувати summary** у stdout/stderr.
|
|
47
|
-
- Сам по собі `run` процес **не завершує** (`process.exit` викликається лише в standalone-гілці нижче).
|
|
48
|
-
- **Як обчислюється цільова тека:** перший аргумент `import.meta.dirname` — це абсолютний шлях до теки правила (`.../npm/rules/nginx-default-tpl/`). `runStandardRule` за цим шляхом резолвить supporting-артефакти: `meta.json`, `check-*.mjs`, MDC-документ, applies-конфіг тощо. Тому **категорично не можна** замінювати `import.meta.dirname` на CWD або жорстко закодований шлях — це зламає інкапсуляцію правила в монорепо.
|
|
49
|
-
|
|
50
|
-
### Top-level CLI-блок (не функція, а імперативний side-effect)
|
|
51
|
-
|
|
52
|
-
```js
|
|
53
|
-
if (isRunAsCli(import.meta.url)) {
|
|
54
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
55
|
-
}
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
- **Умова `isRunAsCli(import.meta.url)`** — детектор того, чи модуль є entry-point (`node fix.mjs` / `bun fix.mjs`), а не імпорт-залежністю. Реалізація утиліти стандартизована в `scripts/lib/run-rule-cli.mjs` (зазвичай порівнює `import.meta.url` з `process.argv[1]`).
|
|
59
|
-
- **`runRuleCli(import.meta.dirname)`** виконує **повний CLI-еквівалент** команди `npx @nitra/cursor fix nginx-default-tpl`:
|
|
60
|
-
- завантаження конфігурації проєкту,
|
|
61
|
-
- застосування whitelist / overrides,
|
|
62
|
-
- друк summary-репорта.
|
|
63
|
-
- **`process.exit(...)`** з результатом `runRuleCli` (number) повертає **exit-code в shell**, щоб CI/IDE могли інтерпретувати «червоний» / «зелений» прогін. Лінт-директиви `n/no-process-exit` і `unicorn/no-process-exit` свідомо вимкнені рядковим коментарем — це задокументоване виключення для **standalone entry-point**, де exit-code є частиною контракту.
|
|
64
|
-
- **Top-level `await`** дозволений у ESM-модулях (`.mjs`) і використовується для уникнення обгортки `(async () => { … })()`.
|
|
65
|
-
|
|
66
|
-
## Залежності
|
|
67
|
-
|
|
68
|
-
### Внутрішні (relative imports)
|
|
69
|
-
|
|
70
|
-
| Імпорт | Із | Що використовується |
|
|
71
|
-
| ----------------- | ----------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
72
|
-
| `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Детектор entry-point — повертає `true`, якщо поточний модуль викликаний напряму CLI-рантаймом. |
|
|
73
|
-
| `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Standalone-orchestration: повний CLI-цикл одного правила (config + whitelist + summary). |
|
|
74
|
-
| `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Library-pipeline правила: `applies → JS-concerns → policy → mdc-refs`. |
|
|
75
|
-
|
|
76
|
-
Шляхи відносні до `npm/rules/nginx-default-tpl/`; `../../scripts/lib/` резолвиться у `npm/scripts/lib/`.
|
|
77
|
-
|
|
78
|
-
### Зовнішні / runtime
|
|
79
|
-
|
|
80
|
-
- **Bun / Node.js ESM** — для `import.meta.dirname` потрібен рантайм з підтримкою `import.meta.dirname` (Node ≥ 20.11 або сучасний Bun). На старіших Node цей геттер повертає `undefined`, що зламає резолв шляхів.
|
|
81
|
-
- **`process.exit`** — глобал Node/Bun рантайму; використовується лише у CLI-гілці.
|
|
82
|
-
|
|
83
|
-
### Типи (JSDoc)
|
|
84
|
-
|
|
85
|
-
`@param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext}` — тип контексту імпортується через JSDoc-тип-імпорт із того ж модуля `runStandardRule`. Це **не runtime-залежність** — лише підказка для TS/IDE.
|
|
86
|
-
|
|
87
|
-
## Потік виконання / Використання
|
|
88
|
-
|
|
89
|
-
### Сценарій 1 — Library mode (batch run)
|
|
90
|
-
|
|
91
|
-
```js
|
|
92
|
-
// Викликається з npm/scripts/run-all-rules.mjs або інших orchestrators
|
|
93
|
-
import { run } from '@nitra/cursor/rules/nginx-default-tpl/fix.mjs'
|
|
94
|
-
|
|
95
|
-
const exitCode = await run({ walkCache })
|
|
96
|
-
if (exitCode !== 0) violatedRules.push('nginx-default-tpl')
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
- Orchestrator передає спільний `walkCache` (чи інший контекст), щоб уникнути повторного обходу файлової системи між правилами.
|
|
100
|
-
- `run` повертає число — orchestrator сам вирішує, чи робити `process.exit` і коли.
|
|
101
|
-
|
|
102
|
-
### Сценарій 2 — Standalone (debug / IDE / CI per-rule)
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
bun npm/rules/nginx-default-tpl/fix.mjs
|
|
106
|
-
# еквівалент:
|
|
107
|
-
npx @nitra/cursor fix nginx-default-tpl
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
- Bun завантажує файл, бачить `isRunAsCli(...) === true`, входить у CLI-гілку.
|
|
111
|
-
- `runRuleCli` сам викликає **той самий** `runStandardRule` під капотом (через `run`-експорт або прямо), але додає завантаження конфігу й whitelist-фільтри.
|
|
112
|
-
- Процес завершується з відповідним exit-кодом — `0` для CI «зелений», `1` для «червоний».
|
|
113
|
-
|
|
114
|
-
### Логічна послідовність всередині `runStandardRule`
|
|
115
|
-
|
|
116
|
-
Згідно з JSDoc-коментарем у `run`, стандартний пайплайн послідовно виконує чотири фази:
|
|
117
|
-
|
|
118
|
-
1. **`applies`** — визначення множини файлів, до яких застосовне правило (за glob-патернами з конфігу правила).
|
|
119
|
-
2. **`JS-concerns`** — JS/TS-специфічні перевірки (синтаксис, AST, imports), якщо релевантно для правила.
|
|
120
|
-
3. **`policy`** — застосування policy-логіки правила (для `nginx-default-tpl` — перевірка/виправлення дефолт-шаблону nginx-конфігурації).
|
|
121
|
-
4. **`mdc-refs`** — крос-валідація з `.mdc`-документом правила (наявність refs, узгодженість прикладів тощо).
|
|
122
|
-
|
|
123
|
-
Деталі та точна семантика фаз залежать від реалізації `runStandardRule` й артефактів самого правила (`check-*.mjs`, `mdc`-файл).
|
|
124
|
-
|
|
125
|
-
### Контракти й нюанси
|
|
126
|
-
|
|
127
|
-
- **Ідемпотентність:** не гарантована на рівні цього wrapper-а — залежить від `runStandardRule`. Зазвичай fix-режим записує патчі на диск і повторний виклик уже повертає `0`.
|
|
128
|
-
- **Concurrency:** глобальне правило монорепо забороняє паралельний запуск кількох правил/лінтерів одночасно (див. CLAUDE.md «Лінт і ESLint (без паралельних запусків)»). У library-режимі orchestrator повинен серіалізувати виклики.
|
|
129
|
-
- **Захищеність від помилок:** wrapper не має власних `try/catch` — будь-який throw з `runStandardRule` чи `runRuleCli` поширюється нагору. У standalone-режимі неперехоплений throw призведе до ненульового exit-коду рантайму (без явного `process.exit(1)`).
|
|
130
|
-
|
|
131
|
-
## Rebuild Test
|
|
132
|
-
|
|
133
|
-
Документ описує **public-контракт** файлу (експорт `run`, його сигнатуру/повернення/побічні ефекти, CLI-гілку з `process.exit`, відносні залежності й послідовність фаз `applies → JS-concerns → policy → mdc-refs`). Цього достатньо для відновлення семантично-еквівалентного wrapper-файлу: створити `.mjs` модуль з ESM-імпортами трьох утиліт, експортувати `run(ctx)`, який повертає `runStandardRule(import.meta.dirname, ctx)`, і додати CLI-блок з `isRunAsCli` + `process.exit(await runRuleCli(import.meta.dirname))`. Сама бізнес-логіка правила `nginx-default-tpl` тут не міститься — вона делегована стандартному пайплайну й артефактам теки.
|
|
35
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
36
|
+
- Кешує результати в межах одного прогону.
|
|
37
|
+
- Не звертається до мережі.
|
|
@@ -1,378 +1,56 @@
|
|
|
1
|
-
# template.mjs — перевірка nginx-шаблону (правило `nginx-default-tpl`)
|
|
2
|
-
|
|
3
|
-
## Огляд
|
|
4
|
-
|
|
5
|
-
Модуль реалізує JS-частину правила `nginx-default-tpl.mdc`. Він шукає у проєкті файли `default.conf.template` (типовий nginx-шаблон, який рендериться `envsubst` під час старту контейнера) і пов'язані з ними артефакти, після чого:
|
|
6
|
-
|
|
7
|
-
1. виконує міграції старих/невалідних артефактів у канонічний вигляд:
|
|
8
|
-
- перейменовує застаріле `default.tpl.conf` у `default.conf.template` (або перезаписує контентом, якщо ціль уже є, після чого видаляє джерело);
|
|
9
|
-
- замінює невалідну директиву `error_log off;` на канонічну `error_log /dev/null crit;`;
|
|
10
|
-
2. перевіряє вміст кожного `default.conf.template` на наявність обов'язкових директив (порт `8080`, `/healthz`, `gzip_static`, `try_files`, `server_tokens off`, `sendfile_max_chunk` тощо) і **відсутність** будь-яких `*_pass` директив (`proxy_pass`, `fastcgi_pass`, `grpc_pass`, `uwsgi_pass` тощо — бекенд-логіка має бути винесена в HTTPRoute на рівні k8s);
|
|
11
|
-
3. перевіряє, що поруч із шаблоном є щонайменше один `*.ini` (values для середовища), а кожен ключ з ini використовується в шаблоні як `$KEY` (контракт `envsubst`);
|
|
12
|
-
4. перевіряє, що в будь-якому `Dockerfile` / `Containerfile` репозиторію є крок стиснення статики `find … /usr/share/nginx/html … gzip -k` і виклик `envsubst` з `default.conf.template`;
|
|
13
|
-
5. делегує валідацію `.vscode/extensions.json` і `.vscode/settings.json` rego-пакетам `nginx_default_tpl.vscode_extensions` / `nginx_default_tpl.vscode_settings` через `runConftestBatch`.
|
|
14
|
-
|
|
15
|
-
Перевірка є **умовною**: якщо в дереві (після міграції) немає жодного `default.conf.template`, увесь крок пропускається з exit-кодом `0`. Приклад HTTPRoute з правила залишений лише для рев'ю — функція `httpRouteMatchesNginxDefaultTpl` присутня в експорті як інструмент для тестів і потенційного майбутнього вузького застосування, але в `check()` зараз **не** викликається (через різнорідність схем маршрутизації в продукті).
|
|
16
|
-
|
|
17
|
-
### Канонічні константи
|
|
18
|
-
|
|
19
|
-
Літерали правила, винесені в регулярні вирази й рядки модуля:
|
|
20
|
-
|
|
21
|
-
- порт listen: `8080`;
|
|
22
|
-
- кореневий каталог статики: `/usr/share/nginx/html`;
|
|
23
|
-
- директива заміни невалідного логу: `error_log /dev/null crit;`;
|
|
24
|
-
- розширення для стиснення: `*.{js,css}` (через `GZIP_EXTENSION_RE`).
|
|
25
|
-
|
|
26
|
-
## Експорти / API
|
|
27
|
-
|
|
28
|
-
Усі експорти — іменовані; default-експорту немає.
|
|
29
|
-
|
|
30
|
-
| Символ | Тип | Призначення |
|
|
31
|
-
| -------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------- |
|
|
32
|
-
| `findDefaultConfTemplatePaths(root, ignorePaths?)` | async function | Збирає абсолютні шляхи всіх `default.conf.template` у дереві (виключаючи `fixtures/`). |
|
|
33
|
-
| `migrateDefaultTplConfFiles(root, ignorePaths?)` | async function | Мігрує застарілі `default.tpl.conf` у `default.conf.template`. |
|
|
34
|
-
| `migrateErrorLogOffDirective(root, ignorePaths?)` | async function | Замінює `error_log off;` на `error_log /dev/null crit;` у всіх знайдених шаблонах. |
|
|
35
|
-
| `parseIniVariableNames(iniText)` | function | Витягує імена ключів з тексту `.ini` (рядки виду `KEY=value`). |
|
|
36
|
-
| `nginxTemplateViolations(content)` | function | Повертає перше порушення канону шаблону або `null`. |
|
|
37
|
-
| `httpRouteMatchesNginxDefaultTpl(manifest)` | function | Перевіряє структуру `HTTPRoute` (зараз не використовується в `check()`). |
|
|
38
|
-
| `iniKeysMissingInTemplate(keys, template)` | function | Повертає повідомлення про першу ключ-змінну з `*.ini`, якої немає в шаблоні як `$KEY`. |
|
|
39
|
-
| `check(cwd?)` | async function | Головна точка входу правила; повертає `0`/`1` як код виходу. |
|
|
40
|
-
|
|
41
|
-
Внутрішні (не експортовані) хелпери:
|
|
42
|
-
|
|
43
|
-
- `dockerfileHasGzipStaticPipeline(dockerfileContent)` — детектор стиснення статики в Dockerfile;
|
|
44
|
-
- `dockerfileHasEnvsSubstTemplate(dockerfileContent)` — детектор кроку `envsubst` із шаблоном;
|
|
45
|
-
- `checkTemplateFile(abs, root, passFn, failFn)` — перевірка одного шаблону й сусідніх `*.ini`;
|
|
46
|
-
- `checkDockerfiles(root, ignorePaths, passFn, failFn)` — перевірка Dockerfile'ів проєкту;
|
|
47
|
-
- `checkVscodeNginx(passFn, failFn, cwd)` — делегування у rego-перевірки VSCode-конфігів.
|
|
48
|
-
|
|
49
|
-
## Функції
|
|
50
|
-
|
|
51
|
-
### `findDefaultConfTemplatePaths(root, ignorePaths = [])`
|
|
52
|
-
|
|
53
|
-
**Сигнатура:** `async (root: string, ignorePaths?: string[]) => Promise<string[]>`
|
|
54
|
-
|
|
55
|
-
**Параметри:**
|
|
56
|
-
|
|
57
|
-
- `root` — абсолютний корінь обходу (зазвичай `process.cwd()` репозиторію);
|
|
58
|
-
- `ignorePaths` — список абсолютних шляхів каталогів, повністю виключених з обходу (зчитується з `.cursorignore` / `.gitignore` через `loadCursorIgnorePaths`).
|
|
59
|
-
|
|
60
|
-
**Повертає:** відсортований (`localeCompare`) масив абсолютних шляхів до файлів з іменем `default.conf.template`.
|
|
61
|
-
|
|
62
|
-
**Поведінка:** обходить дерево через `walkDir`, додає тільки шляхи з базовим іменем `default.conf.template`. Будь-який шлях, у якому хоч один сегмент дорівнює `fixtures`, пропускається — це покриває як кореневі `tests/fixtures/`, так і co-located `rules/<rule>/js/<concern>/fixtures/`. Перед порівнянням бекслеші у відносному шляху нормалізуються в `/` (Windows-safe).
|
|
63
|
-
|
|
64
|
-
**Side effects:** виключно читання дерева ФС через `walkDir`.
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
### `migrateDefaultTplConfFiles(root, ignorePaths = [])`
|
|
69
|
-
|
|
70
|
-
**Сигнатура:** `async (root: string, ignorePaths?: string[]) => Promise<{ renamed: string[], overwritten: string[] }>`
|
|
71
|
-
|
|
72
|
-
**Параметри:** аналогічні `findDefaultConfTemplatePaths`.
|
|
73
|
-
|
|
74
|
-
**Повертає:** об'єкт з двома масивами відносних (від `root`) шляхів колишніх `default.tpl.conf`:
|
|
75
|
-
|
|
76
|
-
- `renamed` — файл був просто перейменований у `default.conf.template`;
|
|
77
|
-
- `overwritten` — поруч уже існував `default.conf.template`, тому його вміст замінено вмістом `default.tpl.conf`, а сам `default.tpl.conf` видалено.
|
|
78
|
-
|
|
79
|
-
**Поведінка:**
|
|
80
|
-
|
|
81
|
-
1. збирає всі `default.tpl.conf` через `walkDir` і сортує їх для детермінованого порядку обробки;
|
|
82
|
-
2. для кожного шляху обчислює цільовий `default.conf.template` у тому ж каталозі (`dirname` + `join`);
|
|
83
|
-
3. якщо ціль існує (`existsSync`) — читає вміст `default.tpl.conf`, записує його в `default.conf.template` (`writeFile` з `utf8`), видаляє джерело (`unlink`);
|
|
84
|
-
4. інакше виконує `rename(old → new)`.
|
|
85
|
-
|
|
86
|
-
**Side effects:** мутація ФС — записи, перейменування, видалення файлів. Усі шляхи в звіті нормалізовані `/`-роздільником.
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
### `migrateErrorLogOffDirective(root, ignorePaths = [])`
|
|
91
|
-
|
|
92
|
-
**Сигнатура:** `async (root: string, ignorePaths?: string[]) => Promise<string[]>`
|
|
93
|
-
|
|
94
|
-
**Параметри:** аналогічні попереднім міграційним функціям.
|
|
95
|
-
|
|
96
|
-
**Повертає:** відносні шляхи шаблонів, у яких було виконано заміну (для звіту `pass`).
|
|
97
|
-
|
|
98
|
-
**Поведінка:** для кожного `default.conf.template`, знайденого `findDefaultConfTemplatePaths`, читає вміст, виконує заміну `ERROR_LOG_OFF_RE → ERROR_LOG_CANONICAL` (тобто `error_log\s+off\s*;` → `error_log /dev/null crit;`). Якщо текст не змінився — файл не переписується (раннє `continue`); інакше — `writeFile` з `utf8`.
|
|
99
|
-
|
|
100
|
-
**Мотивація:** `error_log off;` у nginx **не** валідна директива — `off` трактується як ім'я файлу (`/etc/nginx/off`), і під `readOnlyRootFilesystem` контейнер падає. `/dev/null` — writable character device і коректно «вимикає» лог.
|
|
101
|
-
|
|
102
|
-
**Side effects:** перезапис вмісту шаблонів на місці.
|
|
103
|
-
|
|
104
|
-
---
|
|
105
|
-
|
|
106
|
-
### `parseIniVariableNames(iniText)`
|
|
107
|
-
|
|
108
|
-
**Сигнатура:** `(iniText: string) => string[]`
|
|
109
|
-
|
|
110
|
-
**Параметри:**
|
|
111
|
-
|
|
112
|
-
- `iniText` — повний текст INI-файлу.
|
|
113
|
-
|
|
114
|
-
**Повертає:** масив імен ключів у порядку появи (дублікати не дедуплікуються; вони з'являться стільки разів, скільки разів зустрілися).
|
|
115
|
-
|
|
116
|
-
**Поведінка:** розбиває вхід за `LINE_SPLIT_RE` (`\r?\n`), для кожного рядка обрізає пробіли (`trim()`), пропускає порожні й коментарі (`#`, `;`), решту матчить регексом `INI_KEY_RE = /^([A-Za-z_]\w*)\s*=/` і додає першу групу. Секції (`[section]`) ігноруються природним чином, бо не матчаться регексом.
|
|
117
|
-
|
|
118
|
-
**Side effects:** немає, чиста функція.
|
|
119
|
-
|
|
120
|
-
---
|
|
121
|
-
|
|
122
|
-
### `nginxTemplateViolations(content)`
|
|
123
|
-
|
|
124
|
-
**Сигнатура:** `(content: string) => string | null`
|
|
125
|
-
|
|
126
|
-
**Параметри:**
|
|
127
|
-
|
|
128
|
-
- `content` — повний текст `default.conf.template`.
|
|
129
|
-
|
|
130
|
-
**Повертає:** рядок з першим знайденим порушенням або `null`, якщо шаблон валідний.
|
|
131
|
-
|
|
132
|
-
**Поведінка:** проходить упорядкований список правил і повертає повідомлення першого, чий предикат `ok(content)` повернув `false`. Порядок матеріалізовано в коді; перелік правил, що перевіряються (у порядку виконання):
|
|
133
|
-
|
|
134
|
-
1. наявність `server_tokens off`;
|
|
135
|
-
2. наявність `port_in_redirect off`;
|
|
136
|
-
3. наявність `client_max_body_size 0`;
|
|
137
|
-
4. наявність `client_body_buffer_size 512M`;
|
|
138
|
-
5. наявність `listen 8080`;
|
|
139
|
-
6. наявність `server_name _`;
|
|
140
|
-
7. наявність `access_log off`;
|
|
141
|
-
8. наявність `error_log /dev/null crit` (саме така форма; `error_log off` не валідний);
|
|
142
|
-
9. наявність `root /usr/share/nginx/html`;
|
|
143
|
-
10. `location /healthz` повертає healthy (підрядок `healthy` **або** `return\s+200`);
|
|
144
|
-
11. `location` для статики без gzip — мають бути присутні підрядки `gif|jpe?g|png|ico|woff2|xlsx`, `31536000` та `alias /usr/share/nginx/html/`;
|
|
145
|
-
12. `location` для текстової статики з gzip — підрядок `svg|js|css|ttf|map|xml|webmanifest|wasm`;
|
|
146
|
-
13. `gzip_static on` зустрічається **щонайменше двічі** (для двох location-блоків зі стисненням);
|
|
147
|
-
14. використання `$PUBLIC_PATH` у будь-якому location;
|
|
148
|
-
15. наявність `sendfile on`, `sendfile_max_chunk 512k`, `tcp_nopush on`;
|
|
149
|
-
16. наявність `try_files $uri $uri/ /index.html =404`.
|
|
150
|
-
|
|
151
|
-
Після всіх «позитивних» правил додатково перевіряється негативне: якщо регекс `PROXY_LIKE_RE` (`proxy_pass|proxy_redirect|proxy_set_header|proxy_http_version|fastcgi_pass|grpc_pass|uwsgi_pass`) **матчить** вміст, повертається повідомлення про `*_pass` із вказівкою винести логіку в HTTPRoute. У коді є директива `// cspell:ignore fastcgi uwsgi`, щоб ці назви не лаялися спелчекером.
|
|
152
|
-
|
|
153
|
-
**Side effects:** немає.
|
|
154
|
-
|
|
155
|
-
---
|
|
156
|
-
|
|
157
|
-
### `httpRouteMatchesNginxDefaultTpl(manifest)`
|
|
158
|
-
|
|
159
|
-
**Сигнатура:** `(manifest: unknown) => boolean`
|
|
160
|
-
|
|
161
|
-
**Параметри:**
|
|
162
|
-
|
|
163
|
-
- `manifest` — десеріалізований корінь YAML-документа (об'єкт, мапа, або довільне значення з парсера).
|
|
164
|
-
|
|
165
|
-
**Повертає:** `true`, якщо структура збігається з еталонним прикладом `HTTPRoute` з `nginx-default-tpl.mdc`; інакше `false`.
|
|
166
|
-
|
|
167
|
-
**Поведінка:** ретельно гардить кожен шар від `null`/`undefined`/масивів/не-об'єктів і перевіряє:
|
|
168
|
-
|
|
169
|
-
- `kind === 'HTTPRoute'`;
|
|
170
|
-
- `spec` — об'єкт, не масив;
|
|
171
|
-
- `spec.rules` — масив довжиною ≥ 2;
|
|
172
|
-
- у `rules[0]`:
|
|
173
|
-
- `matches` містить елемент з `path.type === 'Exact'`;
|
|
174
|
-
- `filters` містить елемент з `type === 'RequestRedirect'`, `requestRedirect.scheme === 'https'`, `requestRedirect.path.type === 'ReplaceFullPath'` і `statusCode` `301` (як число або рядок);
|
|
175
|
-
- у `rules[1]`:
|
|
176
|
-
- `matches` містить елемент з `path.type === 'PathPrefix'`;
|
|
177
|
-
- `backendRefs` містить елемент з `port` `8080` (як число або рядок).
|
|
178
|
-
|
|
179
|
-
Підсумок: `hasExact && hasRedirect && hasPrefix && has8080`.
|
|
180
|
-
|
|
181
|
-
**Side effects:** немає. Зараз не викликається з `check()` (зарезервована для тестів і майбутніх перевірок).
|
|
182
|
-
|
|
183
1
|
---
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
**Параметри:**
|
|
190
|
-
|
|
191
|
-
- `keys` — масив імен змінних (зазвичай результат `parseIniVariableNames`);
|
|
192
|
-
- `template` — повний текст `default.conf.template`.
|
|
193
|
-
|
|
194
|
-
**Повертає:** повідомлення про першу змінну, для якої в шаблоні немає підрядка `$KEY`; або `null`, якщо всі ключі присутні.
|
|
195
|
-
|
|
196
|
-
**Поведінка:** простий послідовний перебір `keys` з перевіркою `template.includes('$' + key)`. Це контракт `envsubst`: якщо ключ є у values-ini, він має бути використаний у шаблоні (або вилучений з ini).
|
|
197
|
-
|
|
198
|
-
**Side effects:** немає.
|
|
199
|
-
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/nginx-default-tpl/js/template.mjs
|
|
4
|
+
crc: 2d912e28
|
|
5
|
+
score: 90
|
|
200
6
|
---
|
|
201
7
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
**Сигнатура:** `(dockerfileContent: string) => boolean`
|
|
205
|
-
|
|
206
|
-
**Параметри:**
|
|
207
|
-
|
|
208
|
-
- `dockerfileContent` — повний текст одного Dockerfile/Containerfile.
|
|
209
|
-
|
|
210
|
-
**Повертає:** `true`, якщо в тексті одночасно присутні: `find` (через `FIND_CMD_RE`), підрядок `/usr/share/nginx/html`, `gzip` (через `GZIP_CMD_RE`), прапор `-k` і регекс розширень `*.(js|css)` (через `GZIP_EXTENSION_RE`).
|
|
211
|
-
|
|
212
|
-
**Side effects:** немає.
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
### `dockerfileHasEnvsSubstTemplate(dockerfileContent)` (внутрішня)
|
|
217
|
-
|
|
218
|
-
**Сигнатура:** `(dockerfileContent: string) => boolean`
|
|
219
|
-
|
|
220
|
-
**Параметри:**
|
|
221
|
-
|
|
222
|
-
- `dockerfileContent` — повний текст Dockerfile/Containerfile.
|
|
223
|
-
|
|
224
|
-
**Повертає:** `true`, якщо текст містить одночасно `envsubst` і `default.conf.template`.
|
|
225
|
-
|
|
226
|
-
**Side effects:** немає.
|
|
227
|
-
|
|
228
|
-
---
|
|
229
|
-
|
|
230
|
-
### `checkTemplateFile(abs, root, passFn, failFn)` (внутрішня, async)
|
|
231
|
-
|
|
232
|
-
**Сигнатура:** `async (abs: string, root: string, passFn: (msg: string) => void, failFn: (msg: string) => void) => Promise<void>`
|
|
233
|
-
|
|
234
|
-
**Параметри:**
|
|
8
|
+
# template.mjs
|
|
235
9
|
|
|
236
|
-
|
|
237
|
-
- `root` — корінь репозиторію (для відносних повідомлень);
|
|
238
|
-
- `passFn`, `failFn` — колбеки `createCheckReporter`.
|
|
239
|
-
|
|
240
|
-
**Поведінка:**
|
|
241
|
-
|
|
242
|
-
1. читає шаблон, викликає `nginxTemplateViolations`, рапортує `pass` або `fail` зі стислим описом порушення;
|
|
243
|
-
2. читає сусідній каталог (`readdir(dirname(abs))`); якщо `readdir` падає (наприклад, нет прав), список INI-файлів вважається порожнім (`try/catch`);
|
|
244
|
-
3. з усіх записів обирає тільки ті, що закінчуються на `.ini`;
|
|
245
|
-
4. якщо INI немає — викликає `failFn` з підказкою додати `values-*.ini` і повертається;
|
|
246
|
-
5. інакше — рапортує `pass` про знайдені ini (з кількістю), і для кожного:
|
|
247
|
-
- читає текст (`readFile utf8`); якщо `readFile` падає — рапортує `fail` з повідомленням помилки (`Error.message` або `String(error)` для не-`Error`);
|
|
248
|
-
- інакше парсить імена через `parseIniVariableNames`, передає у `iniKeysMissingInTemplate(keys, content)`; якщо є невикористаний ключ — `fail` з відносним шляхом ini.
|
|
249
|
-
|
|
250
|
-
**Side effects:** читання файлів і каталогів, виклик колбеків репортера.
|
|
251
|
-
|
|
252
|
-
---
|
|
253
|
-
|
|
254
|
-
### `checkDockerfiles(root, ignorePaths, passFn, failFn)` (внутрішня, async)
|
|
255
|
-
|
|
256
|
-
**Сигнатура:** `async (root: string, ignorePaths: string[], passFn, failFn) => Promise<void>`
|
|
257
|
-
|
|
258
|
-
**Поведінка:**
|
|
259
|
-
|
|
260
|
-
1. шукає Dockerfile'и через `findDockerfilePaths(root, ignorePaths)` (імпорт з `../../docker/js/lint.mjs`);
|
|
261
|
-
2. якщо їх немає — `fail` з підказкою (бо `default.conf.template` уже знайдено);
|
|
262
|
-
3. читає вміст усіх Dockerfile'ів `Promise.all`;
|
|
263
|
-
4. якщо **хоч один** має gzip-pipeline (`dockerfileHasGzipStaticPipeline`) — `pass`, інакше `fail`;
|
|
264
|
-
5. якщо **хоч один** має envsubst+template (`dockerfileHasEnvsSubstTemplate`) — `pass`, інакше `fail`.
|
|
265
|
-
|
|
266
|
-
**Side effects:** читання Dockerfile'ів, виклик колбеків.
|
|
267
|
-
|
|
268
|
-
---
|
|
269
|
-
|
|
270
|
-
### `checkVscodeNginx(passFn, failFn, cwd)` (внутрішня, sync)
|
|
271
|
-
|
|
272
|
-
**Сигнатура:** `(passFn, failFn, cwd: string) => void`
|
|
273
|
-
|
|
274
|
-
**Поведінка:** має дві однотипні гілки для `.vscode/extensions.json` і `.vscode/settings.json`:
|
|
275
|
-
|
|
276
|
-
- якщо файл існує — викликає `runConftestBatch` із відповідним `policyDirRel` (`nginx-default-tpl/vscode_extensions` або `…/vscode_settings`) і `namespace` (`nginx_default_tpl.vscode_extensions` / `…vscode_settings`), передає масив з одного файлу. Якщо `violations` порожній — `pass`; інакше для кожного `v` — `failFn(v.message)`;
|
|
277
|
-
- якщо файлу немає — `failFn` з підказкою з `nginx-default-tpl.mdc`.
|
|
278
|
-
|
|
279
|
-
Для `settings.json` при відсутності файлу функція робить ранній `return`, не виконуючи `runConftestBatch` другий раз.
|
|
280
|
-
|
|
281
|
-
**Side effects:** виконання `conftest` як зовнішнього процесу (через `runConftestBatch`), виклик колбеків.
|
|
282
|
-
|
|
283
|
-
---
|
|
284
|
-
|
|
285
|
-
### `check(cwd = process.cwd())`
|
|
286
|
-
|
|
287
|
-
**Сигнатура:** `async (cwd?: string) => Promise<number>`
|
|
288
|
-
|
|
289
|
-
**Параметри:**
|
|
290
|
-
|
|
291
|
-
- `cwd` — корінь репозиторію; за замовчанням `process.cwd()`.
|
|
292
|
-
|
|
293
|
-
**Повертає:** код виходу від `reporter.getExitCode()`: `0`, якщо `failFn` жодного разу не викликався (тільки `pass`); `1` — якщо була хоч одна помилка.
|
|
294
|
-
|
|
295
|
-
**Поведінка (потік виконання):**
|
|
296
|
-
|
|
297
|
-
1. створює репортер `createCheckReporter()` і деструктурує `{ pass, fail }`;
|
|
298
|
-
2. читає список ігнорованих шляхів через `loadCursorIgnorePaths(root)`;
|
|
299
|
-
3. виконує міграцію `default.tpl.conf` → `default.conf.template` (`migrateDefaultTplConfFiles`) і репортує `pass` за кожним перейменованим/перезаписаним файлом;
|
|
300
|
-
4. виконує заміну `error_log off;` (`migrateErrorLogOffDirective`) і репортує `pass` за кожним виправленим шаблоном;
|
|
301
|
-
5. шукає `default.conf.template` (`findDefaultConfTemplatePaths`); якщо їх нуль — `pass` про пропуск і ранній `return reporter.getExitCode()`;
|
|
302
|
-
6. репортує `pass` з кількістю знайдених шаблонів;
|
|
303
|
-
7. послідовно (через `for…of` з `await`) перевіряє кожен шаблон через `checkTemplateFile`;
|
|
304
|
-
8. перевіряє Dockerfile'и через `checkDockerfiles`;
|
|
305
|
-
9. перевіряє VSCode-конфіги через `checkVscodeNginx` (синхронно);
|
|
306
|
-
10. повертає `reporter.getExitCode()`.
|
|
307
|
-
|
|
308
|
-
**Side effects:** виклик усіх міграцій (мутація ФС), читання файлів і каталогів, виконання `conftest` через `runConftestBatch`, запис у репортер.
|
|
309
|
-
|
|
310
|
-
## Залежності
|
|
311
|
-
|
|
312
|
-
### Стандартна бібліотека Node.js
|
|
313
|
-
|
|
314
|
-
- `node:fs` — `existsSync` (синхронна перевірка існування файлу для міграції й VSCode-конфігів);
|
|
315
|
-
- `node:fs/promises` — `readdir`, `readFile`, `rename`, `unlink`, `writeFile`;
|
|
316
|
-
- `node:path` — `basename`, `dirname`, `join`, `relative`.
|
|
10
|
+
## Огляд
|
|
317
11
|
|
|
318
|
-
|
|
12
|
+
Надає повну перевірку проєкту, включаючи перевірку шаблонів, Dockerfile та конфігурацій VSCode.
|
|
319
13
|
|
|
320
|
-
|
|
321
|
-
- `../../../scripts/lib/check-reporter.mjs` — `createCheckReporter()` — стандартний репортер pass/fail з агрегованим exit-кодом;
|
|
322
|
-
- `../../../scripts/lib/load-cursor-config.mjs` — `loadCursorIgnorePaths(root)` — список абсолютних ігнорованих шляхів з `.cursor` конфігу;
|
|
323
|
-
- `../../../scripts/lib/run-conftest-batch.mjs` — `runConftestBatch({ policyDirRel, namespace, files })` — синхронний запуск `conftest` для пакетної перевірки rego;
|
|
324
|
-
- `../../../scripts/utils/walkDir.mjs` — `walkDir(root, visitor, ignorePaths)` — асинхронний обхід дерева.
|
|
14
|
+
## Поведінка
|
|
325
15
|
|
|
326
|
-
|
|
16
|
+
findDefaultConfTemplatePaths
|
|
17
|
+
Збирає абсолютні шляхи до default.conf.template
|
|
327
18
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
- `RETURN_200_RE = /return\s+200/u` — індикатор успішного `/healthz`;
|
|
331
|
-
- `GZIP_STATIC_ON_RE = /gzip_static\s+on/gu` — підрахунок входжень для перевірки «щонайменше 2»;
|
|
332
|
-
- `PROXY_LIKE_RE = /\b(proxy_pass|proxy_redirect|proxy_set_header|proxy_http_version|fastcgi_pass|grpc_pass|uwsgi_pass)\b/u` — заборонені директиви бекенду;
|
|
333
|
-
- `FIND_CMD_RE = /\bfind\b/u`, `GZIP_CMD_RE = /\bgzip\b/u` — детектори команд у Dockerfile;
|
|
334
|
-
- `GZIP_EXTENSION_RE = /\*\.(?:js|css)/u` — детектор маски розширень gzip-кроку;
|
|
335
|
-
- `ERROR_LOG_OFF_RE = /error_log\s+off\s*;/gu` — глобальний регекс для заміни;
|
|
336
|
-
- `ERROR_LOG_CANONICAL = 'error_log /dev/null crit;'` — канонічна заміна.
|
|
19
|
+
migrateDefaultTplConfFiles
|
|
20
|
+
Перейменовує або перезаписує default.tpl.conf у default.conf.template
|
|
337
21
|
|
|
338
|
-
|
|
22
|
+
migrateErrorLogOffDirective
|
|
23
|
+
Замінює невалідну директиву error_log off; на error_log /dev/null crit;
|
|
339
24
|
|
|
340
|
-
|
|
25
|
+
parseIniVariableNames
|
|
26
|
+
Витягує імена змінних з рядків у форматі KEY=value
|
|
341
27
|
|
|
342
|
-
|
|
343
|
-
|
|
28
|
+
nginxTemplateViolations
|
|
29
|
+
Перевіряє вміст шаблону на відповідність вимогам nginx-default-tpl.mdc
|
|
344
30
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
```
|
|
31
|
+
httpRouteMatchesNginxDefaultTpl
|
|
32
|
+
Перевіряє відповідність структури HTTPRoute до прикладу у nginx-default-tpl.mdc
|
|
348
33
|
|
|
349
|
-
|
|
34
|
+
iniKeysMissingInTemplate
|
|
35
|
+
Перевіряє, чи використовуються всі імена змінних з ini у шаблоні
|
|
350
36
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
- застаріле `default.tpl.conf` → `default.conf.template` (rename або overwrite + unlink);
|
|
354
|
-
- невалідне `error_log off;` → `error_log /dev/null crit;`.
|
|
355
|
-
3. **Збір шаблонів:** `findDefaultConfTemplatePaths` (виключає сегменти `fixtures/`).
|
|
356
|
-
4. **Швидкий вихід:** якщо шаблонів нуль — функція повертає `0` як «нічого перевіряти».
|
|
357
|
-
5. **Перевірка кожного шаблону:**
|
|
358
|
-
- валідація директив через `nginxTemplateViolations` (на перше порушення);
|
|
359
|
-
- пошук сусідніх `*.ini`, парс ключів, перевірка `$KEY` у шаблоні через `iniKeysMissingInTemplate`.
|
|
360
|
-
6. **Перевірка Dockerfile'ів:** наявність gzip-кроку для статики й кроку `envsubst` з шаблоном.
|
|
361
|
-
7. **Перевірка VSCode-конфігів:** делегування у rego через `runConftestBatch`.
|
|
362
|
-
8. **Підсумок:** `reporter.getExitCode()` — `0` або `1`.
|
|
37
|
+
check
|
|
38
|
+
Виконує повну валідацію проєкту включаючи перевірку шаблонів, Dockerfile та конфігурацій VSCode
|
|
363
39
|
|
|
364
|
-
|
|
40
|
+
## Публічний API
|
|
365
41
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
42
|
+
findDefaultConfTemplatePaths — Збирає повні шляхи до **default.conf.template** у репозиторії; виключає будь-який сегмент `fixtures/` (включаючи `tests/fixtures/` та ко-локальні шляхи `rules/<rule>/js/<concern>/fixtures/`).
|
|
43
|
+
migrateDefaultTplConfFiles — Знаходить **default.tpl.conf** у дереві від `root`. Якщо **default.conf.template** відсутній, перейменовує **default.tpl.conf**; якщо він присутній, перезаписує **default.conf.template** вмістом **default.tpl.conf** та видаляє **default.tpl.conf**.
|
|
44
|
+
migrateErrorLogOffDirective — Замінює невалідну директиву `error_log off;` на `error_log /dev/null crit;` у всіх **default.conf.template** від `root**. `error_log off;` трактується як ім'я файлу (`/etc/nginx/off`), що призводить до помилки `readOnlyRootFilesystem`. `/dev/null` — це записуваний пристрій.
|
|
45
|
+
parseIniVariableNames — Витягує імена змінних з файлів ini (рядки у форматі KEY=value, без коментарів і порожніх).
|
|
46
|
+
nginxTemplateViolations — Перевіряє вміст **default.conf.template** на відповідність вимогам **nginx-default-tpl.mdc**.
|
|
47
|
+
httpRouteMatchesNginxDefaultTpl — Перевіряє, чи відповідає **HTTPRoute** патерну Exact→RequestRedirect + PathPrefix→backendRefs.
|
|
48
|
+
iniKeysMissingInTemplate — Перевіряє, чи входять усі імена ключів з ini до шаблону у форматі `$KEY` (використовуючи envsubst).
|
|
49
|
+
check — Перевіряє відповідність проєкту правилам **nginx-default-tpl.mdc**.
|
|
371
50
|
|
|
372
|
-
|
|
51
|
+
## Гарантії поведінки
|
|
373
52
|
|
|
374
|
-
-
|
|
375
|
-
-
|
|
376
|
-
-
|
|
377
|
-
-
|
|
378
|
-
- `migrateErrorLogOffDirective` не запускає файлову операцію, якщо вміст не змінився — оптимізація для ідемпотентних запусків.
|
|
53
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
54
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
55
|
+
- Кешує результати в межах одного прогону.
|
|
56
|
+
- Не звертається до мережі.
|