@nitra/cursor 1.11.3 → 1.11.6
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 +32 -3
- package/bin/n-cursor.js +40 -6
- package/package.json +2 -1
- package/rules/abie/js/applies/check.mjs +4 -4
- package/rules/abie/js/env_dns/check.mjs +1 -1
- package/rules/abie/js/firebase_hosting/check.mjs +1 -1
- package/rules/abie/js/hc_pairing/check.mjs +3 -3
- package/rules/abie/js/ua_http_route/check.mjs +3 -3
- package/rules/abie/js/ua_node_selector/check.mjs +4 -2
- package/rules/abie/policy/base_deployment_preem/target.json +1 -5
- package/rules/abie/utils/enabled.mjs +1 -1
- package/rules/abie/utils/env-dns.mjs +4 -4
- package/rules/abie/utils/http-route.mjs +5 -5
- package/rules/abie/utils/k8s-tree.mjs +23 -15
- package/rules/abie/utils/kustomization-patches.mjs +20 -20
- package/rules/abie/utils/overlay-paths.mjs +8 -8
- package/rules/abie/utils/yaml.mjs +4 -4
- package/rules/adr/adr.mdc +2 -2
- package/rules/adr/js/hooks/check.mjs +5 -5
- package/rules/docker/docker.mdc +2 -2
- package/rules/docker/js/run.mjs +3 -2
- package/rules/docker/policy/package_json/package_json.rego +1 -1
- package/rules/ga/js/lint.mjs +3 -26
- package/rules/hasura/js/internal_urls/check.mjs +1 -1
- package/rules/js-bun-redis/js/imports/check.mjs +5 -1
- package/rules/js-run/js/runtime/check.mjs +4 -1
- package/rules/k8s/js/run.mjs +3 -2
- package/rules/k8s/k8s.mdc +2 -4
- package/rules/k8s/policy/base_manifest/target.json +1 -5
- package/rules/nginx-default-tpl/js/template/check.mjs +4 -2
- package/rules/npm-module/js/package_structure/check.mjs +8 -3
- package/rules/npm-module/npm-module.mdc +3 -3
- package/rules/rego/js/applies/check.mjs +2 -2
- package/rules/rego/js/lint.mjs +4 -1
- package/rules/rego/policy/package_json/package_json.rego +5 -3
- package/rules/rego/rego.mdc +3 -3
- package/rules/style-lint/js/tooling/check.mjs +1 -1
- package/rules/style-lint/style-lint.mdc +1 -1
- package/rules/tauri/js/tooling/check.mjs +3 -1
- package/rules/text/js/formatting/check.mjs +8 -24
- package/rules/text/js/lint.mjs +34 -0
- package/rules/text/js/run-shellcheck.mjs +2 -2
- package/rules/text/js/run-v8r.mjs +2 -2
- package/rules/text/text.mdc +5 -5
- package/schemas/v8r-catalog.json +6 -0
- package/scripts/auto-skills.mjs +3 -7
- package/scripts/utils/discover-checkable-rules.mjs +4 -3
- package/scripts/utils/resolve-target-files.mjs +1 -1
- package/scripts/utils/run-lint-step.mjs +33 -0
- package/scripts/utils/run-rule.mjs +5 -3
- package/skills/abie-clean/SKILL.md +13 -11
- package/skills/adr-normalize/SKILL.md +0 -1
- package/skills/fix/SKILL.md +3 -7
- package/rules/abie/policy/base_deployment_preem/base_deployment_preem_test.rego +0 -60
- package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches_test.rego +0 -48
- package/rules/abie/policy/health_check_policy/health_check_policy_test.rego +0 -99
- package/rules/abie/policy/http_route_base/http_route_base_test.rego +0 -64
- package/rules/bun/policy/package_json/package_json_test.rego +0 -109
- package/rules/docker/policy/lint_docker_yml/lint_docker_yml_test.rego +0 -104
- package/rules/docker/policy/package_json/package_json_test.rego +0 -42
- package/rules/graphql/policy/vscode_extensions/vscode_extensions_test.rego +0 -34
- package/rules/image-avif/policy/package_json/package_json_test.rego +0 -69
- package/rules/js-lint/policy/package_json/package_json_test.rego +0 -130
- package/rules/js-run/policy/jsconfig/jsconfig_test.rego +0 -88
- package/rules/k8s/policy/base_kustomization/base_kustomization_test.rego +0 -73
- package/rules/k8s/policy/base_manifest/base_manifest_test.rego +0 -94
- package/rules/k8s/policy/gateway/gateway_test.rego +0 -122
- package/rules/k8s/policy/hasura_configmap/hasura_configmap_test.rego +0 -49
- package/rules/k8s/policy/hasura_httproute/hasura_httproute_test.rego +0 -148
- package/rules/k8s/policy/hpa_pdb/hpa_pdb_test.rego +0 -101
- package/rules/k8s/policy/kustomization/kustomization_test.rego +0 -128
- package/rules/k8s/policy/manifest/manifest_test.rego +0 -309
- package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml_test.rego +0 -42
- package/rules/k8s/policy/svc_yaml/svc_yaml_test.rego +0 -41
- package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions_test.rego +0 -30
- package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings_test.rego +0 -53
- package/rules/npm-module/policy/npm_package_json/npm_package_json_test.rego +0 -81
- package/rules/rego/policy/package_json/package_json_test.rego +0 -42
- package/rules/rego/policy/vscode_extensions/vscode_extensions_test.rego +0 -34
- package/rules/rego/policy/vscode_settings/vscode_settings_test.rego +0 -55
- package/rules/style-lint/policy/vscode_extensions/vscode_extensions_test.rego +0 -39
- package/rules/style-lint/policy/vscode_settings/vscode_settings_test.rego +0 -49
- package/rules/tauri/policy/vscode_extensions/vscode_extensions_test.rego +0 -44
- package/rules/text/policy/markdownlint/markdownlint_test.rego +0 -98
- package/rules/text/policy/vscode_extensions/vscode_extensions_test.rego +0 -51
- package/rules/text/policy/vscode_settings/vscode_settings_test.rego +0 -85
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@
|
|
|
4
4
|
|
|
5
5
|
Формат — [Keep a Changelog](https://keepachangelog.com/uk/1.1.0/), нумерація — [SemVer](https://semver.org/lang/uk/).
|
|
6
6
|
|
|
7
|
+
## [1.11.6] - 2026-05-15
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **`npm/rules/npm-module/npm-module.mdc`** — переформульовано вимогу про тести й фікстури. Раніше правило вимагало тримати їх **поза** будь-яким шляхом з `"files"` (канонічно — у `npm/tests/`). Тепер тести/фікстури можуть лежати **поруч з кодом** усередині `"files"`-шляхів, але `"files"` обовʼязково має містити **негативні glob-патерни**, що виключають їх із tarball (`!**/*.test.*`, `!**/*.spec.*`, `!**/test-helpers.*`, `!**/fixtures/**`, `!**/__tests__/**`, опційно `!**/*_test.rego`). Це краще відповідає реальному layout пакета (co-located test-файли у `rules/<id>/js/<concern>/`) і прибирає роз'їзд правила з фактичним `npm/package.json`. Версію `.mdc` піднято до `1.12`.
|
|
12
|
+
- **`npm/rules/npm-module/js/package_structure/check.mjs::checkNoTestsInPublishedFiles`** — текст fail-повідомлення тепер однозначно радить додати негативний glob у `"files"`, без альтернативи «винеси за межі шляхів з "files"». Логіка перевірки (walk positive ∖ negative + класифікація test-style) не змінилась — пере-кваліфіковано лише підказку для агента й людини.
|
|
13
|
+
|
|
14
|
+
## [1.11.5] - 2026-05-15
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`npm/bin/n-cursor.js`** — підкоманди `lint-rego`, `lint-k8s`, `lint-docker`, `lint-text` (раніше був лише `lint-ga`). Споживчі `package.json` тепер можуть використовувати уніфіковану форму `n-cursor lint-X` замість прямих посилань на файли `bun ./npm/scripts/*.mjs`, які після phase 2 концерн-сплету переїхали у `npm/rules/<id>/js/`. `lint-text` — композитний: послідовно `cspell .` → `runShellcheckText()` → `bunx markdownlint-cli2 --fix "**/*.md" "**/*.mdc"` → `runV8rWithGlobs()`.
|
|
19
|
+
- **`npm/rules/text/js/lint.mjs`** — новий ентрі-модуль для канонічного `lint-text`.
|
|
20
|
+
- **`npm/scripts/utils/run-lint-step.mjs`** — спільний хелпер `runLintStep(title, cmd, args)` для CLI-обгорток `lint-<rule>` (раніше дублювалося у `rules/ga/js/lint.mjs` і новому `rules/text/js/lint.mjs` — jscpd-clone).
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **`npm/rules/k8s/js/run.mjs`**, **`npm/rules/docker/js/run.mjs`** — `main()` перейменовано і експортовано як `runLintK8s` / `runLintDocker` для виклику з CLI-маршрутизатора. `isRunAsCli()`-гілка прямого запуску збережена для зворотної сумісності.
|
|
25
|
+
- **`npm/rules/rego/js/lint.mjs`** — авто-виклик `runLintRego()` тепер обгорнуто `if (isRunAsCli())`, інакше імпорт модуля з CLI запускав би лінт як side-effect.
|
|
26
|
+
- **`npm/rules/rego/policy/package_json/`** — канонічне значення `scripts.lint-rego` змінено на `"n-cursor lint-rego"` (раніше `"bun ./npm/scripts/lint-rego.mjs"`). Аналогічно `npm/rules/docker/policy/package_json/` — на `"n-cursor lint-docker"`.
|
|
27
|
+
- **`npm/rules/text/js/formatting/check.mjs`** — `checkLintTextScript()` тепер вимагає рівно `"n-cursor lint-text"` замість попередньої складної валідації багатоступеневого ланцюжка (`cspell` → `run-shellcheck-text.mjs` → `markdownlint-cli2` → `run-v8r.mjs`). Канонічна форма — одне посилання на CLI, а зміст ланцюжка живе у `npm/rules/text/js/lint.mjs`.
|
|
28
|
+
- **`npm/package.json#files`** — додано негативний glob `"!**/*_test.rego"` (раніше були лише `*.test.mjs`, `test-helpers.mjs`, `fixtures/**`). 33 rego-юніт-тестових файли (`<policy>_test.rego`) більше не потрапляють у tarball — їх виконує лише `conftest verify` у dev-репо.
|
|
29
|
+
|
|
30
|
+
## [1.11.4] - 2026-05-15
|
|
31
|
+
|
|
32
|
+
### Fixed
|
|
33
|
+
|
|
34
|
+
- **`npm/rules/nginx-default-tpl/js/template/check.mjs`** — `findDefaultConfTemplatePaths` пропускає тестові `fixtures/` за будь-яким сегментом шляху, не лише `tests/fixtures/`. Після concern-split (фази 1-4) fixtures лежать у `rules/<rule>/js/<concern>/fixtures/`, і старий патерн пропускав їх повз → check шукав Dockerfile поруч із тестовим шаблоном і фалс-фейлив.
|
|
35
|
+
|
|
7
36
|
## [1.11.3] - 2026-05-15
|
|
8
37
|
|
|
9
38
|
### Fixed
|
|
@@ -55,7 +84,7 @@
|
|
|
55
84
|
- **Інкрементальна міграція правил на `target.json`** (декларативні маніфести поруч із кожним `<concern>.rego`):
|
|
56
85
|
- **Single-file правила** (11): `bun`, `text`, `style-lint`, `php`, `docker`, `npm-module`, `js-lint`, `image-compress`, `capacitor`, `hasura`, `adr` — `target.json` з `single` для кожного канонічного конфіг-файлу. Сумарно 27 нових маніфестів. `bun.bunfig`, `text.cspell`, `npm_module.npm_publish_yml` тощо тепер прогоняються через CLI `check <id>` без додаткового `bun run lint-conftest`.
|
|
57
86
|
- **Walk-glob правила** (6): `js-mssql`, `js-bun-db`, `js-bun-redis`, `js-run` (package_json + configmap), `vue`, `image-avif` — `walkGlob: "**/package.json"` або відповідний патерн.
|
|
58
|
-
- **k8s
|
|
87
|
+
- **k8s.\* концерни** (8): `manifest`, `gateway`, `hpa_pdb`, `kustomization`, `svc_yaml`, `svc_hl_yaml`, `base_kustomization`, `base_manifest` — `walkGlob` по YAML під сегментом `k8s/`; `base_manifest` використовує негативний glob для виключення `kustomization.yaml`.
|
|
59
88
|
- **abie концерни** (4): `clean_merged_ignore_branches` (single), `health_check_policy` (walkGlob `**/k8s/**/hc.yaml`), `http_route_base` (walkGlob `**/k8s/**/base/**/hr.yaml`), `base_deployment_preem` (walkGlob `**/k8s/**/base/**/*.{yaml,yml}` з виключенням `kustomization.yaml`).
|
|
60
89
|
- **`capture-decisions.sh` тепер пише чернетки напряму в `docs/adr/<timestamp>-<sid>.md`** (раніше — у `docs/adr/_inbox/`). Сам каталог `_inbox/` більше не створюється, але `normalize-decisions.sh` бачить його рекурсивно — старі чернетки з `_inbox/` поступово розчищаються нормалізацією. Можна також одноразово `git mv docs/adr/_inbox/*.md docs/adr/` і прибрати порожній каталог.
|
|
61
90
|
- **Правило `adr` (`npm/rules/adr/adr.mdc`)**: повне переписування під дві фази (capture + normalize). Видалено згадки `_inbox/`. Версія `version: '2.0'`.
|
|
@@ -77,14 +106,14 @@
|
|
|
77
106
|
|
|
78
107
|
### Fixed
|
|
79
108
|
|
|
80
|
-
- `npm/package.json#files`: додано негативні glob-патерни `!**/*.test.mjs`, `!**/test-helpers.mjs`, `!**/fixtures/**`, щоб після переїзду тестів у `rules/<rule>/js/`, `scripts/`, `scripts/utils/` вони не потрапляли в опубліковану npm
|
|
109
|
+
- `npm/package.json#files`: додано негативні glob-патерни `!**/*.test.mjs`, `!**/test-helpers.mjs`, `!**/fixtures/**`, щоб після переїзду тестів у `rules/<rule>/js/`, `scripts/`, `scripts/utils/` вони не потрапляли в опубліковану npm-tarball (вимагає правило `npm-module`).
|
|
81
110
|
- `npm/package.json#devDependencies`: додано `@nitra/cursor: ^1.9.22` (auto-fill від `ensure-nitra-cursor-dev-dependencies.mjs`).
|
|
82
111
|
|
|
83
112
|
## [1.9.22] - 2026-05-14
|
|
84
113
|
|
|
85
114
|
### Changed
|
|
86
115
|
|
|
87
|
-
- **Rule-centric структура пакета.** Кожне правило тепер живе в одній директорії `npm/rules/{rule}/` з усіма своїми артефактами: `{rule}.mdc`, `auto.md` (умова автоактивації), `policy/` (rego-поліси), `js/` (check.mjs + опційні run/lint + co-located
|
|
116
|
+
- **Rule-centric структура пакета.** Кожне правило тепер живе в одній директорії `npm/rules/{rule}/` з усіма своїми артефактами: `{rule}.mdc`, `auto.md` (умова автоактивації), `policy/` (rego-поліси), `js/` (check.mjs + опційні run/lint + co-located \*.test.mjs + fixtures/). Видалив каталог правила — правило зникло без слідів у `bin/auto-rules.md`, `npm/policy/`, `npm/scripts/`. Дзеркальна структура для скілів у `npm/skills/{skill}/` (SKILL.md + auto.md + js/).
|
|
88
117
|
- **Тести співрозташовуються з джерелами.** ~50 файлів з `npm/tests/` переїхали в `npm/rules/{rule}/js/*.test.mjs` (тести правил), `npm/scripts/*.test.mjs` (тести інфраструктури), `npm/scripts/utils/*.test.mjs` (тести утиліт). `tests/helpers.mjs` → `scripts/utils/test-helpers.mjs`. `npm/tests/` залишається тільки для 3 крос-правильних інтеграційних тестів.
|
|
89
118
|
- **`bin/n-cursor.js`**: `BUNDLED_MDC_DIR` → `BUNDLED_RULES_DIR`. `discoverBundledRuleNames` і `discoverCheckScripts` тепер обходять підкаталоги `rules/` замість файлів у `mdc/` чи `check-*.mjs` у `scripts/`. Резолвер check-скриптів: `rules/{rule}/js/check.mjs`. `readBundledRuleContent` читає `rules/{rule}/{rule}.mdc`.
|
|
90
119
|
- **`scripts/utils/run-conftest-batch.mjs` та `scripts/lint-conftest.mjs`**: шляхи до rego-полісі — `rules/{rule}/policy/{name}/` (замість `policy/{rule}/{name}/`). Snake_case `policyDirRel` у JS-call sites замінено на kebab-case.
|
package/bin/n-cursor.js
CHANGED
|
@@ -13,6 +13,12 @@
|
|
|
13
13
|
* інакше викликає `check`); прописується автоматично в `.claude/settings.json`
|
|
14
14
|
* `npx \@nitra/cursor lint-ga` — канонічний lint-ga (ga.mdc): preflight на `shellcheck` →
|
|
15
15
|
* `bunx github-actionlint` → `uvx zizmor --offline --collect=workflows .`
|
|
16
|
+
* `npx \@nitra/cursor lint-rego` — канонічний lint-rego (conftest.mdc + rego.mdc):
|
|
17
|
+
* preflight на `opa`/`regal` → `opa check --strict` → `regal lint` → опц. `conftest verify`
|
|
18
|
+
* `npx \@nitra/cursor lint-k8s` — канонічний lint-k8s (k8s.mdc): `kubeconform` + `kubescape` по `…/k8s/*.yaml`
|
|
19
|
+
* `npx \@nitra/cursor lint-docker` — канонічний lint-docker (docker.mdc): `hadolint` по `Dockerfile`/`*.Dockerfile`
|
|
20
|
+
* `npx \@nitra/cursor lint-text` — канонічний lint-text (text.mdc): `cspell` → `shellcheck` (з auto-fix) →
|
|
21
|
+
* `markdownlint-cli2 --fix` → `v8r` (json/json5/yaml/yml/toml)
|
|
16
22
|
*
|
|
17
23
|
* Claude Code інтеграція: під час синку, окрім `.cursor/rules` і `.claude/commands` (з skills), CLI ще раз
|
|
18
24
|
* синхронізує `.claude/settings.json` (hooks + permissions; merge — користувацькі поля зберігаються),
|
|
@@ -68,7 +74,11 @@ import { detectAutoSkills } from '../scripts/auto-skills.mjs'
|
|
|
68
74
|
import { runStopHookCli } from '../scripts/claude-stop-hook.mjs'
|
|
69
75
|
import { discoverCheckableRules } from '../scripts/utils/discover-checkable-rules.mjs'
|
|
70
76
|
import { ensureNitraCursorInRootDevDependencies } from '../scripts/ensure-nitra-cursor-dev-dependencies.mjs'
|
|
77
|
+
import { runLintDocker } from '../rules/docker/js/run.mjs'
|
|
71
78
|
import { runLintGaCli } from '../rules/ga/js/lint.mjs'
|
|
79
|
+
import { runLintK8s } from '../rules/k8s/js/run.mjs'
|
|
80
|
+
import { runLintRego } from '../rules/rego/js/lint.mjs'
|
|
81
|
+
import { runLintTextCli } from '../rules/text/js/lint.mjs'
|
|
72
82
|
import { runRule } from '../scripts/utils/run-rule.mjs'
|
|
73
83
|
import { syncClaudeConfig } from '../scripts/sync-claude-config.mjs'
|
|
74
84
|
import { upgradeNitraCursorToLatestAndBunInstall } from '../scripts/upgrade-nitra-cursor-and-install.mjs'
|
|
@@ -88,7 +98,6 @@ const RULE_PREFIX = 'n-'
|
|
|
88
98
|
|
|
89
99
|
const binDir = dirname(fileURLToPath(import.meta.url))
|
|
90
100
|
const BUNDLED_RULES_DIR = join(binDir, '..', 'rules')
|
|
91
|
-
const BUNDLED_SCRIPTS_DIR = join(binDir, '..', 'scripts')
|
|
92
101
|
const BUNDLED_SKILLS_DIR = join(binDir, '..', 'skills')
|
|
93
102
|
const BUNDLED_AGENTS_TEMPLATE_PATH = join(binDir, '..', AGENTS_TEMPLATE_FILE)
|
|
94
103
|
/** Корінь установленого пакету (каталог з `rules/`, `github-actions/`, …) */
|
|
@@ -266,8 +275,9 @@ async function readConfig(paths = {}) {
|
|
|
266
275
|
// правило, додане вручну (напр. `adr` без auto.md-умови), не активувало б залежні
|
|
267
276
|
// скіли (`adr-normalize`).
|
|
268
277
|
const disableRulesSet = new Set(disableRules)
|
|
269
|
-
const effectiveRulesForSkills = [
|
|
270
|
-
.
|
|
278
|
+
const effectiveRulesForSkills = [
|
|
279
|
+
...new Set([...normalizeIdList(parsedConfig.rules), ...autoDetectedRules.rules])
|
|
280
|
+
].filter(id => !disableRulesSet.has(id))
|
|
271
281
|
const autoDetectedSkills = detectAutoSkills({
|
|
272
282
|
availableSkills,
|
|
273
283
|
detectedRules: effectiveRulesForSkills,
|
|
@@ -999,9 +1009,9 @@ function logRemovedManagedItems(title, basePath, names) {
|
|
|
999
1009
|
* (плюс legacy `rules/<id>/js/check.mjs` як концерн `legacy`) або policy-концерн у
|
|
1000
1010
|
* `rules/<id>/policy/<concern>/target.json`. Делегує у `discoverCheckableRules` —
|
|
1001
1011
|
* див. `scripts/utils/discover-checkable-rules.mjs`.
|
|
1002
|
-
* @returns {
|
|
1012
|
+
* @returns {import('../scripts/utils/discover-checkable-rules.mjs').CheckableRule[]} опис правил у алфавітному порядку
|
|
1003
1013
|
*/
|
|
1004
|
-
|
|
1014
|
+
function discoverCheckScripts() {
|
|
1005
1015
|
return discoverCheckableRules(BUNDLED_RULES_DIR)
|
|
1006
1016
|
}
|
|
1007
1017
|
|
|
@@ -1347,6 +1357,30 @@ try {
|
|
|
1347
1357
|
|
|
1348
1358
|
break
|
|
1349
1359
|
}
|
|
1360
|
+
case 'lint-rego': {
|
|
1361
|
+
// Канонічний lint-rego: preflight opa/regal → opa check --strict → regal lint → conftest verify (опц.).
|
|
1362
|
+
process.exitCode = runLintRego()
|
|
1363
|
+
|
|
1364
|
+
break
|
|
1365
|
+
}
|
|
1366
|
+
case 'lint-k8s': {
|
|
1367
|
+
// Канонічний lint-k8s: kubeconform + kubescape по знайдених деревах `…/k8s/*.yaml`.
|
|
1368
|
+
process.exitCode = await runLintK8s()
|
|
1369
|
+
|
|
1370
|
+
break
|
|
1371
|
+
}
|
|
1372
|
+
case 'lint-docker': {
|
|
1373
|
+
// Канонічний lint-docker: hadolint по Dockerfile та *.Dockerfile (docker.mdc).
|
|
1374
|
+
process.exitCode = await runLintDocker()
|
|
1375
|
+
|
|
1376
|
+
break
|
|
1377
|
+
}
|
|
1378
|
+
case 'lint-text': {
|
|
1379
|
+
// Канонічний lint-text: cspell → run-shellcheck → markdownlint-cli2 --fix → run-v8r (text.mdc).
|
|
1380
|
+
process.exitCode = runLintTextCli()
|
|
1381
|
+
|
|
1382
|
+
break
|
|
1383
|
+
}
|
|
1350
1384
|
case undefined:
|
|
1351
1385
|
case '': {
|
|
1352
1386
|
await runSync()
|
|
@@ -1356,7 +1390,7 @@ try {
|
|
|
1356
1390
|
default: {
|
|
1357
1391
|
console.error(`❌ Невідома команда: ${command}`)
|
|
1358
1392
|
console.error(
|
|
1359
|
-
` Очікується: (без аргументів) синхронізація правил, check, rename-yaml-extensions, stop-hook, lint-ga`
|
|
1393
|
+
` Очікується: (без аргументів) синхронізація правил, check, rename-yaml-extensions, stop-hook, lint-ga, lint-rego, lint-k8s, lint-docker, lint-text`
|
|
1360
1394
|
)
|
|
1361
1395
|
process.exitCode = 1
|
|
1362
1396
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nitra/cursor",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.6",
|
|
4
4
|
"description": "CLI для завантаження cursor-правил (префікс n-) у локальний репозиторій",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"AGENTS.template.md",
|
|
35
35
|
"CHANGELOG.md",
|
|
36
36
|
"!**/*.test.mjs",
|
|
37
|
+
"!**/*_test.rego",
|
|
37
38
|
"!**/test-helpers.mjs",
|
|
38
39
|
"!**/fixtures/**"
|
|
39
40
|
],
|
|
@@ -8,16 +8,16 @@ import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mj
|
|
|
8
8
|
import { isAbieRuleEnabled } from '../../utils/enabled.mjs'
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
|
-
* @returns {Promise<boolean>}
|
|
11
|
+
* @returns {Promise<boolean>} `true` — правило застосовне; `false` — пропустити
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
13
|
+
export function applies() {
|
|
14
14
|
return isAbieRuleEnabled(process.cwd())
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* @returns {
|
|
18
|
+
* @returns {number} exit-код (0 — OK, 1 — порушення)
|
|
19
19
|
*/
|
|
20
|
-
export
|
|
20
|
+
export function check() {
|
|
21
21
|
const reporter = createCheckReporter()
|
|
22
22
|
reporter.pass('Правило abie увімкнено — виконуємо перевірки')
|
|
23
23
|
return reporter.getExitCode()
|
|
@@ -15,7 +15,7 @@ import { loadCursorIgnorePaths } from '../../../../scripts/utils/load-cursor-con
|
|
|
15
15
|
import { abieEnvNameFromBasename, collectAbieEnvFiles, validateAbieEnvInternalUrls } from '../../utils/env-dns.mjs'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* @returns {Promise<number>}
|
|
18
|
+
* @returns {Promise<number>} результат
|
|
19
19
|
*/
|
|
20
20
|
export async function check() {
|
|
21
21
|
const reporter = createCheckReporter()
|
|
@@ -12,7 +12,7 @@ import { createCheckReporter } from '../../../../scripts/utils/check-reporter.mj
|
|
|
12
12
|
const SKIP_TOP_DIR_NAMES = new Set(['.git', 'node_modules'])
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* @returns {Promise<number>}
|
|
15
|
+
* @returns {Promise<number>} результат
|
|
16
16
|
*/
|
|
17
17
|
export async function check() {
|
|
18
18
|
const reporter = createCheckReporter()
|
|
@@ -17,7 +17,7 @@ import { validateAbieHcModeline } from '../../utils/hc-yaml.mjs'
|
|
|
17
17
|
import { collectDeploymentDirs, findK8sYamlFiles } from '../../utils/k8s-tree.mjs'
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* @returns {Promise<number>}
|
|
20
|
+
* @returns {Promise<number>} результат
|
|
21
21
|
*/
|
|
22
22
|
export async function check() {
|
|
23
23
|
const reporter = createCheckReporter()
|
|
@@ -50,8 +50,8 @@ export async function check() {
|
|
|
50
50
|
continue
|
|
51
51
|
}
|
|
52
52
|
const modelineErr = validateAbieHcModeline(hcRaw, relHc)
|
|
53
|
-
if (modelineErr
|
|
54
|
-
else
|
|
53
|
+
if (modelineErr === null) pass(`${relHc}: modeline OK`)
|
|
54
|
+
else fail(modelineErr)
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
return reporter.getExitCode()
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
} from '../../utils/overlay-paths.mjs'
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
|
-
* @returns {Promise<number>}
|
|
29
|
+
* @returns {Promise<number>} результат
|
|
30
30
|
*/
|
|
31
31
|
export async function check() {
|
|
32
32
|
const reporter = createCheckReporter()
|
|
@@ -78,8 +78,8 @@ export async function check() {
|
|
|
78
78
|
}
|
|
79
79
|
const combined = getCombinedNginxRunPatchTextFromKustomization(raw)
|
|
80
80
|
const v = validateAbieNginxRunHttpRoutePatches(combined, 'ua', raw, sharedAnalysis.refCount)
|
|
81
|
-
if (v
|
|
82
|
-
else
|
|
81
|
+
if (v === null) pass(`${rel}: HTTPRoute patch (ua) відповідає abie.mdc`)
|
|
82
|
+
else fail(`${rel}: ${v}`)
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
return reporter.getExitCode()
|
|
@@ -16,7 +16,7 @@ import { kustomizationHasAbieDeploymentNodeSelectorPatch } from '../../utils/kus
|
|
|
16
16
|
import { abieOverlayK8sTreeHasDeployment, isUaKustomizationPath } from '../../utils/overlay-paths.mjs'
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
|
-
* @returns {Promise<number>}
|
|
19
|
+
* @returns {Promise<number>} результат
|
|
20
20
|
*/
|
|
21
21
|
export async function check() {
|
|
22
22
|
const reporter = createCheckReporter()
|
|
@@ -55,7 +55,9 @@ export async function check() {
|
|
|
55
55
|
continue
|
|
56
56
|
}
|
|
57
57
|
if (!kustomizationHasAbieDeploymentNodeSelectorPatch(raw, 'ua')) {
|
|
58
|
-
fail(
|
|
58
|
+
fail(
|
|
59
|
+
`${rel}: потрібен patch target kind Deployment: path /spec/template/spec/nodeSelector та preem: false (abie.mdc)`
|
|
60
|
+
)
|
|
59
61
|
continue
|
|
60
62
|
}
|
|
61
63
|
pass(`${rel}: nodeSelector patch (ua) відповідає abie.mdc`)
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://unpkg.com/@nitra/cursor/schemas/target.json",
|
|
3
3
|
"files": {
|
|
4
|
-
"walkGlob": [
|
|
5
|
-
"**/k8s/**/base/**/*.yaml",
|
|
6
|
-
"**/k8s/**/base/**/*.yml",
|
|
7
|
-
"!**/k8s/**/base/**/kustomization.yaml"
|
|
8
|
-
]
|
|
4
|
+
"walkGlob": ["**/k8s/**/base/**/*.yaml", "**/k8s/**/base/**/*.yml", "!**/k8s/**/base/**/kustomization.yaml"]
|
|
9
5
|
}
|
|
10
6
|
}
|
|
@@ -12,7 +12,7 @@ const CONFIG_FILE = '.n-cursor.json'
|
|
|
12
12
|
/**
|
|
13
13
|
* Чи увімкнено правило **abie** у `.n-cursor.json:rules`.
|
|
14
14
|
* @param {string} root корінь репозиторію (cwd)
|
|
15
|
-
* @returns {Promise<boolean>}
|
|
15
|
+
* @returns {Promise<boolean>} `true` — `rules` містить `abie`; `false` — інакше
|
|
16
16
|
*/
|
|
17
17
|
export async function isAbieRuleEnabled(root) {
|
|
18
18
|
const p = join(root, CONFIG_FILE)
|
|
@@ -23,8 +23,8 @@ const ABIE_ENV_CLUSTER_DNS_MAP = Object.freeze({
|
|
|
23
23
|
/**
|
|
24
24
|
* Дістає `dev` / `ua` з basename env-файлу abie.
|
|
25
25
|
* Не-abie env-файли (`production.env`, `.env` без імені) → null.
|
|
26
|
-
* @param {string} basenameOfEnvFile
|
|
27
|
-
* @returns {('dev' | 'ua') | null}
|
|
26
|
+
* @param {string} basenameOfEnvFile опис.
|
|
27
|
+
* @returns {('dev' | 'ua') | null} результат
|
|
28
28
|
*/
|
|
29
29
|
export function abieEnvNameFromBasename(basenameOfEnvFile) {
|
|
30
30
|
const m = basenameOfEnvFile.match(ABIE_ENV_FILE_BASENAME_RE)
|
|
@@ -35,7 +35,7 @@ export function abieEnvNameFromBasename(basenameOfEnvFile) {
|
|
|
35
35
|
* Сканує вміст env-файла, повертає помилки невідповідності кластерного DNS / namespace
|
|
36
36
|
* для кожного internal URL (один URL у двох змінних = дві окремі помилки).
|
|
37
37
|
* @param {string} content вміст env-файла (UTF-8)
|
|
38
|
-
* @param {'dev' | 'ua'} envName
|
|
38
|
+
* @param {'dev' | 'ua'} envName опис.
|
|
39
39
|
* @returns {string[]} порожній масив, якщо все OK
|
|
40
40
|
*/
|
|
41
41
|
export function validateAbieEnvInternalUrls(content, envName) {
|
|
@@ -63,7 +63,7 @@ export function validateAbieEnvInternalUrls(content, envName) {
|
|
|
63
63
|
* Збирає `*.env` файли, які є abie env (`dev.env`/`ua.env`, опц. з провідною крапкою).
|
|
64
64
|
* @param {string} root корінь репозиторію
|
|
65
65
|
* @param {string[]} ignorePaths абсолютні шляхи каталогів-виключень
|
|
66
|
-
* @returns {Promise<string[]>}
|
|
66
|
+
* @returns {Promise<string[]>} результат
|
|
67
67
|
*/
|
|
68
68
|
export async function collectAbieEnvFiles(root, ignorePaths) {
|
|
69
69
|
/** @type {string[]} */
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Cross-документна аналітика abie HTTPRoute: підрахунок `backendRefs` до спільних
|
|
3
3
|
* сервісів (`auth-run-hl`, `file-link-hl`) у base-маніфестах пакета (поза overlay `ua`).
|
|
4
4
|
* Використовується ua_http_route-концерном для синхронізації числа patch-ів namespace
|
|
5
|
-
* у overlay із кількістю base-
|
|
5
|
+
* у overlay із кількістю base-reference.
|
|
6
6
|
*/
|
|
7
7
|
import { relative } from 'node:path'
|
|
8
8
|
|
|
@@ -14,7 +14,7 @@ const ABIE_SHARED_CROSS_NS_BACKEND_SET = new Set(ABIE_SHARED_CROSS_NS_BACKEND_NA
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Перевіряє один `backendRef`: якщо це спільний `-hl` сервіс, має бути `namespace: dev`.
|
|
17
|
-
* @param {unknown} br
|
|
17
|
+
* @param {unknown} br опис.
|
|
18
18
|
* @param {string} rel rel-шлях файла
|
|
19
19
|
* @param {string[]} errors мутабельний список помилок
|
|
20
20
|
* @returns {number} 1 — це shared backend, 0 — інакше
|
|
@@ -33,8 +33,8 @@ function checkSharedBackendRef(br, rel, errors) {
|
|
|
33
33
|
/**
|
|
34
34
|
* Збирає по HTTPRoute-документу кількість посилань на shared backends і порушення namespace.
|
|
35
35
|
* @param {unknown} obj корінь YAML
|
|
36
|
-
* @param {string} rel
|
|
37
|
-
* @returns {{ refCount: number, errors: string[] }}
|
|
36
|
+
* @param {string} rel опис.
|
|
37
|
+
* @returns {{ refCount: number, errors: string[] }} статистика shared-backend посилань і порушення namespace
|
|
38
38
|
*/
|
|
39
39
|
function httpRouteDocSharedCrossNsBackendStats(obj, rel) {
|
|
40
40
|
/** @type {string[]} */
|
|
@@ -66,7 +66,7 @@ function httpRouteDocSharedCrossNsBackendStats(obj, rel) {
|
|
|
66
66
|
* @param {string} root корінь репозиторію
|
|
67
67
|
* @param {string} pkgAbs абсолютний шлях каталогу пакета
|
|
68
68
|
* @param {string[]} yamlFilesAbs усі yaml під k8s
|
|
69
|
-
* @returns {Promise<{ refCount: number, baseErrors: string[] }>}
|
|
69
|
+
* @returns {Promise<{ refCount: number, baseErrors: string[] }>} агрегована статистика й помилки base-шару
|
|
70
70
|
*/
|
|
71
71
|
export async function analyzeAbieSharedBackendRefsInPackageK8s(root, pkgAbs, yamlFilesAbs) {
|
|
72
72
|
const pkgRel = relative(root, pkgAbs).replaceAll('\\', '/') || pkgAbs
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Кеш — module-level singleton, ключований за `(root, ignorePaths)`. Перший виклик
|
|
7
7
|
* платить за обхід; наступні концерни в межах того ж прогону отримують готове.
|
|
8
|
-
* Для тестів — `resetAbieK8sTreeCache()` (інакше withTmpCwd-фікстури злипатимуться).
|
|
9
8
|
*/
|
|
10
9
|
import { dirname, relative } from 'node:path'
|
|
11
10
|
|
|
@@ -20,20 +19,11 @@ const yamlCache = new Map()
|
|
|
20
19
|
/** @type {Map<string, Promise<Set<string>>>} */
|
|
21
20
|
const deploymentCache = new Map()
|
|
22
21
|
|
|
23
|
-
/**
|
|
24
|
-
* Скидає кеш — тести мусять викликати між фікстурами.
|
|
25
|
-
* @returns {void}
|
|
26
|
-
*/
|
|
27
|
-
export function resetAbieK8sTreeCache() {
|
|
28
|
-
yamlCache.clear()
|
|
29
|
-
deploymentCache.clear()
|
|
30
|
-
}
|
|
31
|
-
|
|
32
22
|
/**
|
|
33
23
|
* Стабільний ключ кешу за (root, ignorePaths).
|
|
34
|
-
* @param {string} root
|
|
35
|
-
* @param {string[]} ignorePaths
|
|
36
|
-
* @returns {string}
|
|
24
|
+
* @param {string} root опис.
|
|
25
|
+
* @param {string[]} ignorePaths опис.
|
|
26
|
+
* @returns {string} результат
|
|
37
27
|
*/
|
|
38
28
|
function cacheKey(root, ignorePaths) {
|
|
39
29
|
return `${root}|${[...ignorePaths].toSorted((a, b) => a.localeCompare(b)).join(':')}`
|
|
@@ -44,7 +34,7 @@ function cacheKey(root, ignorePaths) {
|
|
|
44
34
|
* Каталог `.github/` свідомо пропускається (належить `ga.mdc`).
|
|
45
35
|
* @param {string} root корінь репозиторію
|
|
46
36
|
* @param {string[]} [ignorePaths] абсолютні шляхи каталогів-виключень
|
|
47
|
-
* @returns {Promise<string[]>}
|
|
37
|
+
* @returns {Promise<string[]>} результат
|
|
48
38
|
*/
|
|
49
39
|
export function findK8sYamlFiles(root, ignorePaths = []) {
|
|
50
40
|
const key = cacheKey(root, ignorePaths)
|
|
@@ -77,7 +67,25 @@ export function findK8sYamlFiles(root, ignorePaths = []) {
|
|
|
77
67
|
* @param {(msg: string) => void} [fail] репортер помилок парсингу (опц.)
|
|
78
68
|
* @returns {Promise<Set<string>>} абсолютні шляхи директорій
|
|
79
69
|
*/
|
|
80
|
-
|
|
70
|
+
/**
|
|
71
|
+
* No-op fail-handler за замовчуванням для `collectDeploymentDirs` — пошкоджені YAML
|
|
72
|
+
* під час cross-rule сканування мовчки пропускаються; формальний reporter передає сам caller.
|
|
73
|
+
* @param {string} _msg повідомлення про помилку (ігнорується)
|
|
74
|
+
*/
|
|
75
|
+
const silentFail = _msg => {
|
|
76
|
+
// noop
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Знаходить унікальні каталоги, що містять Deployment-маніфести серед переданих YAML-файлів.
|
|
81
|
+
* Парсить документи через `readAndParseYamlDocs` і фільтрує лише ті, що є Deployment.
|
|
82
|
+
* Кешує результат за ключем `root|<sorted yamlAbs>`, щоб повторні виклики не робили I/O.
|
|
83
|
+
* @param {string} root абсолютний корінь репо для побудови relative-шляхів у повідомленнях
|
|
84
|
+
* @param {string[]} yamlAbs абсолютні шляхи до YAML-файлів для перевірки
|
|
85
|
+
* @param {(msg: string) => void} [fail] callback на помилку парсингу (за замовчуванням noop)
|
|
86
|
+
* @returns {Promise<Set<string>>} проміс із сетом абсолютних каталогів, де знайдено Deployment
|
|
87
|
+
*/
|
|
88
|
+
export function collectDeploymentDirs(root, yamlAbs, fail = silentFail) {
|
|
81
89
|
const key = `${root}|${[...yamlAbs].toSorted((a, b) => a.localeCompare(b)).join(':')}`
|
|
82
90
|
const cached = deploymentCache.get(key)
|
|
83
91
|
if (cached) return cached
|
|
@@ -24,8 +24,8 @@ const ABIE_UA_HTTPROUTE_HOST_MARKERS = ['abie.app', 'vybeerai.com.ua', '*.abie.a
|
|
|
24
24
|
|
|
25
25
|
/**
|
|
26
26
|
* Чи patch-рядок містить очікуваний ua nodeSelector (preem: false).
|
|
27
|
-
* @param {string} patchText
|
|
28
|
-
* @returns {boolean}
|
|
27
|
+
* @param {string} patchText опис.
|
|
28
|
+
* @returns {boolean} результат
|
|
29
29
|
*/
|
|
30
30
|
function jsonPatchTextHasUaDeploymentNodeSelector(patchText) {
|
|
31
31
|
if (typeof patchText !== 'string' || patchText.trim() === '') return false
|
|
@@ -36,9 +36,9 @@ function jsonPatchTextHasUaDeploymentNodeSelector(patchText) {
|
|
|
36
36
|
|
|
37
37
|
/**
|
|
38
38
|
* Чи один елемент `patches` відповідає abie nodeSelector для `mode`.
|
|
39
|
-
* @param {unknown} p
|
|
40
|
-
* @param {'ua'} mode
|
|
41
|
-
* @returns {boolean}
|
|
39
|
+
* @param {unknown} p опис.
|
|
40
|
+
* @param {'ua'} mode опис.
|
|
41
|
+
* @returns {boolean} результат
|
|
42
42
|
*/
|
|
43
43
|
function inlineKustomizationPatchMatchesAbieMode(p, mode) {
|
|
44
44
|
if (p === null || typeof p !== 'object' || Array.isArray(p)) return false
|
|
@@ -55,9 +55,9 @@ function inlineKustomizationPatchMatchesAbieMode(p, mode) {
|
|
|
55
55
|
|
|
56
56
|
/**
|
|
57
57
|
* Чи документ Kustomization містить відповідний inline patch на Deployment.
|
|
58
|
-
* @param {import('yaml').Document} doc
|
|
59
|
-
* @param {'ua'} mode
|
|
60
|
-
* @returns {boolean}
|
|
58
|
+
* @param {import('yaml').Document} doc опис.
|
|
59
|
+
* @param {'ua'} mode опис.
|
|
60
|
+
* @returns {boolean} результат
|
|
61
61
|
*/
|
|
62
62
|
function kustomizationDocumentHasAbieDeploymentNodeSelectorPatch(doc, mode) {
|
|
63
63
|
if (doc.errors.length > 0) return false
|
|
@@ -76,8 +76,8 @@ function kustomizationDocumentHasAbieDeploymentNodeSelectorPatch(doc, mode) {
|
|
|
76
76
|
/**
|
|
77
77
|
* Чи `kustomization.yaml` містить валідні inline patch для Deployment nodeSelector (ua).
|
|
78
78
|
* @param {string} raw повний текст файла
|
|
79
|
-
* @param {'ua'} mode
|
|
80
|
-
* @returns {boolean}
|
|
79
|
+
* @param {'ua'} mode опис.
|
|
80
|
+
* @returns {boolean} результат
|
|
81
81
|
*/
|
|
82
82
|
export function kustomizationHasAbieDeploymentNodeSelectorPatch(raw, mode) {
|
|
83
83
|
const body = stripBom(raw)
|
|
@@ -100,8 +100,8 @@ export function kustomizationHasAbieDeploymentNodeSelectorPatch(raw, mode) {
|
|
|
100
100
|
// ── HTTPRoute (ua) ────────────────────────────────────────────────────────
|
|
101
101
|
|
|
102
102
|
/**
|
|
103
|
-
* @param {unknown} p
|
|
104
|
-
* @returns {string | null}
|
|
103
|
+
* @param {unknown} p опис.
|
|
104
|
+
* @returns {string | null} результат
|
|
105
105
|
*/
|
|
106
106
|
function extractHttpRoutePatchString(p) {
|
|
107
107
|
if (p === null || typeof p !== 'object' || Array.isArray(p)) return null
|
|
@@ -116,8 +116,8 @@ function extractHttpRoutePatchString(p) {
|
|
|
116
116
|
|
|
117
117
|
/**
|
|
118
118
|
* Збирає inline `patch`-рядки для HTTPRoute (непорожній `target.name`) з одного Kustomization-документа.
|
|
119
|
-
* @param {import('yaml').Document} doc
|
|
120
|
-
* @returns {string[]}
|
|
119
|
+
* @param {import('yaml').Document} doc опис.
|
|
120
|
+
* @returns {string[]} результат
|
|
121
121
|
*/
|
|
122
122
|
function collectAbieHttpRoutePatchStringsFromKustomizationDoc(doc) {
|
|
123
123
|
if (doc.errors.length > 0) return []
|
|
@@ -137,7 +137,7 @@ function collectAbieHttpRoutePatchStringsFromKustomizationDoc(doc) {
|
|
|
137
137
|
/**
|
|
138
138
|
* Збирає всі inline JSON6902-фрагменти HTTPRoute (непорожній `target.name`) у kustomization.yaml.
|
|
139
139
|
* @param {string} raw повний текст файла
|
|
140
|
-
* @returns {string}
|
|
140
|
+
* @returns {string} результат
|
|
141
141
|
*/
|
|
142
142
|
export function getCombinedNginxRunPatchTextFromKustomization(raw) {
|
|
143
143
|
const body = stripBom(raw)
|
|
@@ -162,8 +162,8 @@ export function getCombinedNginxRunPatchTextFromKustomization(raw) {
|
|
|
162
162
|
/**
|
|
163
163
|
* Рахує операції JSON6902 з `path: /spec/rules/.../backendRefs/.../namespace` і `value: ua[-…]`.
|
|
164
164
|
* @param {string} combined сукупний текст patch
|
|
165
|
-
* @param {'ua'} mode
|
|
166
|
-
* @returns {number}
|
|
165
|
+
* @param {'ua'} mode опис.
|
|
166
|
+
* @returns {number} результат
|
|
167
167
|
*/
|
|
168
168
|
function countAbieHttpRouteBackendRefNamespacePatchesInCombined(combined, mode) {
|
|
169
169
|
if (mode !== 'ua') return 0
|
|
@@ -175,7 +175,7 @@ function countAbieHttpRouteBackendRefNamespacePatchesInCombined(combined, mode)
|
|
|
175
175
|
/**
|
|
176
176
|
* Перевіряє сукупний текст patch(ів) HTTPRoute на відповідність abie.mdc.
|
|
177
177
|
* @param {string} combined сукупний текст patch
|
|
178
|
-
* @param {'ua'} mode
|
|
178
|
+
* @param {'ua'} mode опис.
|
|
179
179
|
* @param {string} [_fullKustomizationRaw] зберігається для API-сумісності, не використовується
|
|
180
180
|
* @param {number} [sharedCrossNsBackendRefCount] кількість `auth-run-hl`/`file-link-hl` у base HTTPRoute
|
|
181
181
|
* @returns {string | null} повідомлення про помилку або null
|
|
@@ -215,8 +215,8 @@ export function validateAbieNginxRunHttpRoutePatches(
|
|
|
215
215
|
/**
|
|
216
216
|
* Чи kustomization містить валідні patch для HTTPRoute (ua).
|
|
217
217
|
* @param {string} raw повний текст kustomization.yaml
|
|
218
|
-
* @param {'ua'} mode
|
|
219
|
-
* @returns {boolean}
|
|
218
|
+
* @param {'ua'} mode опис.
|
|
219
|
+
* @returns {boolean} результат
|
|
220
220
|
*/
|
|
221
221
|
export function kustomizationHasAbieNginxRunHttpRoutePatch(raw, mode) {
|
|
222
222
|
const combined = getCombinedNginxRunPatchTextFromKustomization(raw)
|
|
@@ -16,8 +16,8 @@ const TRAILING_SLASH_RE = /\/$/u
|
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Чи `rel` — це `…/ua/kustomization.yaml` (abie overlay).
|
|
19
|
-
* @param {string} rel
|
|
20
|
-
* @returns {boolean}
|
|
19
|
+
* @param {string} rel posix-шлях від кореня репозиторію
|
|
20
|
+
* @returns {boolean} результат
|
|
21
21
|
*/
|
|
22
22
|
export function isUaKustomizationPath(rel) {
|
|
23
23
|
const norm = rel.replaceAll('\\', '/')
|
|
@@ -28,7 +28,7 @@ export function isUaKustomizationPath(rel) {
|
|
|
28
28
|
* Каталог пакета (батько `k8s/`) для overlay `…/k8s/ua/kustomization.yaml`.
|
|
29
29
|
* @param {string} root корінь репозиторію
|
|
30
30
|
* @param {string} kustomizationAbs абсолютний шлях до ua kustomization
|
|
31
|
-
* @returns {string | null}
|
|
31
|
+
* @returns {string | null} результат
|
|
32
32
|
*/
|
|
33
33
|
export function abiePackageDirFromK8sOverlay(root, kustomizationAbs) {
|
|
34
34
|
const rel = relative(root, kustomizationAbs).replaceAll('\\', '/') || kustomizationAbs
|
|
@@ -41,7 +41,7 @@ export function abiePackageDirFromK8sOverlay(root, kustomizationAbs) {
|
|
|
41
41
|
* застосовується лише до Vite-пакетів.
|
|
42
42
|
* @param {string} root корінь репозиторію
|
|
43
43
|
* @param {string} kustomizationAbs абсолютний шлях до ua kustomization
|
|
44
|
-
* @returns {boolean}
|
|
44
|
+
* @returns {boolean} результат
|
|
45
45
|
*/
|
|
46
46
|
export function abieOverlayRequiresHttpRouteByVite(root, kustomizationAbs) {
|
|
47
47
|
const pkg = abiePackageDirFromK8sOverlay(root, kustomizationAbs)
|
|
@@ -58,7 +58,7 @@ export function abieOverlayRequiresHttpRouteByVite(root, kustomizationAbs) {
|
|
|
58
58
|
* @param {Set<string>} deploymentDirs абсолютні каталоги з Deployment
|
|
59
59
|
* @param {string} root корінь репозиторію
|
|
60
60
|
* @param {string} kustomizationAbs абсолютний шлях до ua kustomization
|
|
61
|
-
* @returns {boolean}
|
|
61
|
+
* @returns {boolean} результат
|
|
62
62
|
*/
|
|
63
63
|
export function abieOverlayK8sTreeHasDeployment(deploymentDirs, root, kustomizationAbs) {
|
|
64
64
|
const pkg = abiePackageDirFromK8sOverlay(root, kustomizationAbs)
|
|
@@ -73,8 +73,8 @@ export function abieOverlayK8sTreeHasDeployment(deploymentDirs, root, kustomizat
|
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Чи rel-шлях `…/k8s/base/…` (base-шар abie, не overlay).
|
|
76
|
-
* @param {string} rel
|
|
77
|
-
* @returns {boolean}
|
|
76
|
+
* @param {string} rel опис.
|
|
77
|
+
* @returns {boolean} результат
|
|
78
78
|
*/
|
|
79
79
|
export function isAbieK8sBaseYamlPath(rel) {
|
|
80
80
|
const norm = rel.replaceAll('\\', '/')
|
|
@@ -85,7 +85,7 @@ export function isAbieK8sBaseYamlPath(rel) {
|
|
|
85
85
|
* Чи yaml належить до `<pkgRel>/k8s/**` поза `ua/` піддеревом (base-шар abie).
|
|
86
86
|
* @param {string} relFromRoot шлях від кореня
|
|
87
87
|
* @param {string} pkgRelFromRoot каталог пакета від кореня
|
|
88
|
-
* @returns {boolean}
|
|
88
|
+
* @returns {boolean} результат
|
|
89
89
|
*/
|
|
90
90
|
export function isK8sYamlInAbiePackageExcludingUaOverlay(relFromRoot, pkgRelFromRoot) {
|
|
91
91
|
const normRel = relFromRoot.replaceAll('\\', '/')
|
|
@@ -12,7 +12,7 @@ export const LINE_SPLIT_RE = /\r?\n/u
|
|
|
12
12
|
/**
|
|
13
13
|
* Прибирає BOM на початку файлу.
|
|
14
14
|
* @param {string} s вміст
|
|
15
|
-
* @returns {string}
|
|
15
|
+
* @returns {string} результат
|
|
16
16
|
*/
|
|
17
17
|
export function stripBom(s) {
|
|
18
18
|
return s.startsWith('') ? s.slice(1) : s
|
|
@@ -21,7 +21,7 @@ export function stripBom(s) {
|
|
|
21
21
|
/**
|
|
22
22
|
* Чи YAML-документ — це `kind: Deployment`.
|
|
23
23
|
* @param {unknown} obj корінь YAML-документа
|
|
24
|
-
* @returns {boolean}
|
|
24
|
+
* @returns {boolean} результат
|
|
25
25
|
*/
|
|
26
26
|
export function isDeploymentDoc(obj) {
|
|
27
27
|
return (
|
|
@@ -46,8 +46,8 @@ export const silentFail = _msg => {
|
|
|
46
46
|
* викликає `failFn` і повертає `null`.
|
|
47
47
|
* @param {string} abs абсолютний шлях
|
|
48
48
|
* @param {string} rel відносний (для повідомлень)
|
|
49
|
-
* @param {(msg: string) => void} failFn
|
|
50
|
-
* @returns {Promise<import('yaml').Document[] | null>}
|
|
49
|
+
* @param {(msg: string) => void} failFn опис.
|
|
50
|
+
* @returns {Promise<import('yaml').Document[] | null>} результат
|
|
51
51
|
*/
|
|
52
52
|
export async function readAndParseYamlDocs(abs, rel, failFn) {
|
|
53
53
|
let raw
|