@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,388 +1,34 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/js-run/js/runtime.mjs
|
|
4
|
+
crc: 9c22e999
|
|
5
|
+
score: 90
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Модуль `npm/rules/js-run/js/runtime.mjs` — це **виконавча частина** правила `js-run.mdc`
|
|
6
|
-
для монорепо-перевірки командою `npx @nitra/cursor check`. Він обходить усі workspace-пакети
|
|
7
|
-
(виключаючи кореневий `.`) і для кожного пакета валідує дотримання набору JS-/інфраструктурних
|
|
8
|
-
конвенцій, які складно або неможливо виразити лише через Rego-політики per-document.
|
|
9
|
-
|
|
10
|
-
Покрите цим модулем:
|
|
11
|
-
|
|
12
|
-
- **Заборона `@nitra/bunyan` / `bunyan` в імпортах коду** — статичні `import`, CommonJS
|
|
13
|
-
`require`, динамічний `import()`; знаходиться через AST-парсер (`oxc-parser`, делегується
|
|
14
|
-
в `../lib/bunyan-imports.mjs`).
|
|
15
|
-
- **`OTEL_RESOURCE_ATTRIBUTES` у `k8s/base/configmap.yaml`** — наявність файлу (структуру
|
|
16
|
-
валідує Rego через `npx @nitra/cursor fix`, namespace `js_run.configmap`).
|
|
17
|
-
- **Внутрішні аліаси `#conn/*`** — імпорти `bun#SQL`, `mssql`, `@nitra/graphql-request#GraphQLClient`
|
|
18
|
-
дозволені лише в каталозі `src/conn/` (або в каталозі, заданому `package.json#imports['#conn/*']`).
|
|
19
|
-
- **Нейминг і експорти у `#conn/`** — `ql-<id>` / `(pg|mysql|mssql)-(read|write)[-<id>]`;
|
|
20
|
-
`export default` заборонений; іменований експорт має дорівнювати camelCase від basename файла;
|
|
21
|
-
`index.*` пропускається як reexport-барель.
|
|
22
|
-
- **`process.env` / `CheckEnv`** — пряме `process.env.X` заборонене; обов'язкові змінні —
|
|
23
|
-
через `env` з `@nitra/check-env` + `checkEnv(['X', …])` у тому ж файлі (або коментар
|
|
24
|
-
`// @nitra/cursor ignore-next-line checkEnv`); опційні — через `env` з `node:process`.
|
|
25
|
-
- **Паузи через `setTimeout`** — `new Promise(r => setTimeout(r, ms))` має бути замінений на
|
|
26
|
-
`await setTimeout(ms)` з `node:timers/promises`.
|
|
27
|
-
- **`jsconfig.json` у backend-пакеті з `src/`** — наявність файла (структуру `NodeNext` і
|
|
28
|
-
`include: src/**/*` валідує Rego `js_run.jsconfig` через `runConftestBatch`).
|
|
29
|
-
|
|
30
|
-
Per-document валідація `package.json` (заборона `@nitra/bunyan`/`bunyan` у залежностях,
|
|
31
|
-
правила для `node` у `scripts`) делегована окремому rego-пакету `js_run.package_json` у
|
|
32
|
-
`npm/rules/js-run/policy/package_json/`; цей JS-файл — про крос-файлові й AST-перевірки.
|
|
33
|
-
|
|
34
|
-
Frontend-пакети (з `vite` у `devDependencies`) повністю пропускаються — для них
|
|
35
|
-
актуальний інший контекст (браузерний бандл без `node:process`); bunyan-залежність
|
|
36
|
-
такого пакета все одно перевіряється Rego-частиною.
|
|
37
|
-
|
|
38
|
-
## Експорти / API
|
|
39
|
-
|
|
40
|
-
| Експорт | Тип | Призначення |
|
|
41
|
-
| ------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------- |
|
|
42
|
-
| `check(cwd?)` | `async function` | Єдина публічна точка входу. Запускає перевірку всіх workspace-пакетів. Повертає `0` (все OK) або `1` (є порушення). |
|
|
43
|
-
|
|
44
|
-
Усі інші функції модуля — внутрішні (без `export`) і використовуються лише з `check`.
|
|
45
|
-
|
|
46
|
-
## Функції
|
|
47
|
-
|
|
48
|
-
### `check(cwd = process.cwd())` _(export)_
|
|
49
|
-
|
|
50
|
-
- **Сигнатура:** `async function check(cwd?: string): Promise<number>`
|
|
51
|
-
- **Параметри:**
|
|
52
|
-
- `cwd` _(string, опційний)_ — абсолютний корінь репозиторію; за замовчуванням
|
|
53
|
-
`process.cwd()`.
|
|
54
|
-
- **Повертає:** `Promise<number>` — exit-код від `createCheckReporter().getExitCode()`
|
|
55
|
-
(0 — успіх, 1 — є хоча б одне `fail(...)`).
|
|
56
|
-
- **Side effects:**
|
|
57
|
-
- читає `package.json` коренева/workspace-пакетів через `getMonorepoPackageRootDirs`;
|
|
58
|
-
- читає `.cursorignore` / конфіг через `loadCursorIgnorePaths`;
|
|
59
|
-
- читає файли пакетів (`fs/promises`), синхронні `existsSync` / `statSync`;
|
|
60
|
-
- друкує повідомлення `pass(...)` / `fail(...)` через репортер;
|
|
61
|
-
- запускає `conftest` через `runConftestBatch` (зовнішній процес) для перевірки `jsconfig.json`.
|
|
62
|
-
- **Алгоритм:**
|
|
63
|
-
1. Створює репортер `createCheckReporter()`.
|
|
64
|
-
2. Бере список усіх коренів пакетів і відфільтровує кореневий `.`.
|
|
65
|
-
3. Якщо workspace-пакетів немає — викликає `pass(...)` з відповідним повідомленням
|
|
66
|
-
і повертає exit-код.
|
|
67
|
-
4. Завантажує перелік `ignorePaths` (повністю виключені з обходу).
|
|
68
|
-
5. По черзі викликає `checkWorkspacePackage(r, ignorePaths, fail, pass, cwd)` для кожного `r`.
|
|
69
|
-
6. Повертає `reporter.getExitCode()`.
|
|
70
|
-
|
|
71
|
-
### `checkWorkspacePackage(rootDir, ignorePaths, fail, passFn, cwd)`
|
|
72
|
-
|
|
73
|
-
- **Сигнатура:**
|
|
74
|
-
`async function checkWorkspacePackage(rootDir: string, ignorePaths: string[], fail: (msg: string) => void, passFn: (msg: string) => void, cwd: string): Promise<void>`
|
|
75
|
-
- **Параметри:**
|
|
76
|
-
- `rootDir` — відносний шлях workspace-пакета (не `'.'`).
|
|
77
|
-
- `ignorePaths` — абсолютні шляхи каталогів, виключені з обходу.
|
|
78
|
-
- `fail` — callback реєстрації порушення.
|
|
79
|
-
- `passFn` — callback повідомлення про успішну під-перевірку.
|
|
80
|
-
- `cwd` — корінь репозиторію.
|
|
81
|
-
- **Повертає:** `Promise<void>`.
|
|
82
|
-
- **Side effects:** читає `package.json` пакета; запускає всі під-перевірки нижче;
|
|
83
|
-
для frontend-пакета (vite у `devDependencies`) повертається одразу після `passFn`.
|
|
84
|
-
- **Алгоритм:**
|
|
85
|
-
1. Формує `label = '[<rootDir>] '` і `absPackageRoot`.
|
|
86
|
-
2. Завантажує `pkgJson = loadPackageJson(rootDir, cwd)`.
|
|
87
|
-
3. Якщо `packageJsonHasViteDevDependency(pkgJson)` — `passFn(...)` і вихід.
|
|
88
|
-
4. `checkBackendJsconfigWhenSrcPresent(...)` — gate на `jsconfig.json`.
|
|
89
|
-
5. `checkBunyanImports(...)` → якщо `0` порушень, друкує позитивне повідомлення.
|
|
90
|
-
6. `collectSourceFiles(...)` — спільний список JS/TS-файлів для подальших сканів.
|
|
91
|
-
7. `checkConnImports(...)` → позитивне повідомлення з резолвленим `connDir`.
|
|
92
|
-
8. `checkConnFileNamingAndExports(...)` → позитивне повідомлення про канон у `connDir/`.
|
|
93
|
-
9. `checkProcessEnvUsage(...)` → позитивне повідомлення про `process.env`/`checkEnv`.
|
|
94
|
-
10. `checkPromiseSetTimeoutPause(...)` → позитивне повідомлення про `setTimeout`-паузи.
|
|
95
|
-
11. `checkOtelConfigmap(...)` — лише наявність `k8s/base/configmap.yaml`.
|
|
96
|
-
|
|
97
|
-
### `backendPackageHasSrcDir(absPackageRoot)`
|
|
98
|
-
|
|
99
|
-
- **Сигнатура:** `function backendPackageHasSrcDir(absPackageRoot: string): boolean`
|
|
100
|
-
- **Параметри:** `absPackageRoot` — абсолютний корінь пакета.
|
|
101
|
-
- **Повертає:** `true`, якщо `<absPackageRoot>/src` існує і це каталог.
|
|
102
|
-
- **Side effects:** синхронний `statSync`; помилки ловить і повертає `false`.
|
|
103
|
-
|
|
104
|
-
### `checkBackendJsconfigWhenSrcPresent(rootDir, absPackageRoot, label, fail, passFn, cwd)`
|
|
105
|
-
|
|
106
|
-
- **Сигнатура:**
|
|
107
|
-
`function checkBackendJsconfigWhenSrcPresent(rootDir: string, absPackageRoot: string, label: string, fail: (msg: string) => void, passFn: (msg: string) => void, cwd: string): void`
|
|
108
|
-
- **Параметри:** як у `checkWorkspacePackage`.
|
|
109
|
-
- **Повертає:** `void`.
|
|
110
|
-
- **Side effects:** `existsSync` для `jsconfig.json`; виклик `runConftestBatch` (зовнішній
|
|
111
|
-
процес `conftest`); виклик `fail`/`passFn`.
|
|
112
|
-
- **Алгоритм:**
|
|
113
|
-
1. Якщо `src/` відсутній — повернутися (gate перевірки).
|
|
114
|
-
2. Якщо `jsconfig.json` відсутній — `fail(...)` із повідомленням про канонічний файл і вихід.
|
|
115
|
-
3. Викликає `runConftestBatch({ policyDirRel: 'js-run/jsconfig', namespace: 'js_run.jsconfig', files: [jcPath] })`.
|
|
116
|
-
4. Якщо порушень немає — `passFn(...)`; інакше — `fail(...)` для кожного.
|
|
117
|
-
|
|
118
|
-
### `relPosix(absPackageRoot, absPath)`
|
|
119
|
-
|
|
120
|
-
- **Сигнатура:** `function relPosix(absPackageRoot: string, absPath: string): string`
|
|
121
|
-
- **Параметри:** корінь пакета й абсолютний шлях до файлу.
|
|
122
|
-
- **Повертає:** відносний шлях у posix-форматі (`/`), отриманий заміною `\\` → `/` у результаті
|
|
123
|
-
`node:path#relative`.
|
|
124
|
-
- **Side effects:** немає (чиста функція).
|
|
125
|
-
|
|
126
|
-
### `checkBunyanImports(absPackageRoot, ignorePaths, label, fail)`
|
|
127
|
-
|
|
128
|
-
- **Сигнатура:**
|
|
129
|
-
`async function checkBunyanImports(absPackageRoot: string, ignorePaths: string[], label: string, fail: (msg: string) => void): Promise<number>`
|
|
130
|
-
- **Повертає:** кількість знайдених порушень.
|
|
131
|
-
- **Side effects:** `walkDir` (читання каталогу), `readFile` для кожного source-файла, виклик `fail`.
|
|
132
|
-
- **Алгоритм:**
|
|
133
|
-
1. Збирає `sourcePaths` обходом `walkDir`, фільтр: `!shouldSkipFileForBunyanScan(rel) && isBunyanScanSourceFile(rel)`.
|
|
134
|
-
2. Для кожного — читає вміст і викликає `findBunyanImportsInText(content, rel)`.
|
|
135
|
-
3. Для кожного `v` друкує повідомлення з номером рядка, ім'ям модуля й snippet'ом і
|
|
136
|
-
інкрементує лічильник.
|
|
137
|
-
|
|
138
|
-
### `collectSourceFiles(absPackageRoot, ignorePaths)`
|
|
139
|
-
|
|
140
|
-
- **Сигнатура:**
|
|
141
|
-
`async function collectSourceFiles(absPackageRoot: string, ignorePaths: string[]): Promise<string[]>`
|
|
142
|
-
- **Повертає:** масив абсолютних шляхів до файлів-кандидатів на скан (фільтр
|
|
143
|
-
`isCheckEnvScanSourceFile`).
|
|
144
|
-
- **Side effects:** `walkDir`. Зверніть увагу: фільтр базується саме на правилах
|
|
145
|
-
`check-env-scan`, але отриманий список потім перевикористовується для інших сканів
|
|
146
|
-
(`conn-imports`, `conn-file-rules`, `process-env`, `promise-settimeout`), кожен з яких
|
|
147
|
-
має свій додатковий внутрішній фільтр (`isConnImportsScanSourceFile` тощо).
|
|
148
|
-
|
|
149
|
-
### `checkConnImports(absPackageRoot, sourcePaths, pkgJson, label, fail)`
|
|
150
|
-
|
|
151
|
-
- **Сигнатура:**
|
|
152
|
-
`async function checkConnImports(absPackageRoot: string, sourcePaths: string[], pkgJson: unknown, label: string, fail: (msg: string) => void): Promise<number>`
|
|
153
|
-
- **Повертає:** кількість порушень.
|
|
154
|
-
- **Side effects:** `readFile`, `fail`.
|
|
155
|
-
- **Алгоритм:**
|
|
156
|
-
1. `connDir = resolveConnDirFromPackageJson(pkgJson)`.
|
|
157
|
-
2. Для кожного файла зі `sourcePaths`:
|
|
158
|
-
- пропускає, якщо не source-file для conn-imports-scan;
|
|
159
|
-
- пропускає, якщо файл вже всередині `connDir/`;
|
|
160
|
-
- читає вміст, викликає `findConnFactoryImportsInText(content, rel)` і друкує
|
|
161
|
-
повідомлення `fail(...)` із форматуванням `{ <specifier> } from '<module>'` або
|
|
162
|
-
`'<module>'` (коли `specifier === '*'`).
|
|
163
|
-
|
|
164
|
-
### `checkConnFileNamingAndExports(absPackageRoot, sourcePaths, pkgJson, label, fail)`
|
|
165
|
-
|
|
166
|
-
- **Сигнатура:**
|
|
167
|
-
`async function checkConnFileNamingAndExports(absPackageRoot: string, sourcePaths: string[], pkgJson: unknown, label: string, fail: (msg: string) => void): Promise<number>`
|
|
168
|
-
- **Повертає:** кількість порушень.
|
|
169
|
-
- **Side effects:** `readFile`, `fail`.
|
|
170
|
-
- **Алгоритм:** для кожного файла, який `isConnFileToCheck(rel, connDir)`, читає вміст і
|
|
171
|
-
для кожного `v` з `findConnFileRuleViolations(content, rel)` друкує повідомлення з
|
|
172
|
-
`formatConnFileViolation(v, label, rel, connDir)`.
|
|
173
|
-
|
|
174
|
-
### `isConnFileToCheck(rel, connDir)`
|
|
175
|
-
|
|
176
|
-
- **Сигнатура:** `function isConnFileToCheck(rel: string, connDir: string): boolean`
|
|
177
|
-
- **Повертає:** `true`, коли файл:
|
|
178
|
-
- лежить всередині `connDir/` (`isInsideConnDir`);
|
|
179
|
-
- має розширення JS/TS, що відповідає `isConnFileRulesSourceFile`;
|
|
180
|
-
- basename **не** починається з `index.` (бо це reexport-барель).
|
|
8
|
+
# runtime.mjs
|
|
181
9
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- **Сигнатура:**
|
|
185
|
-
`function formatConnFileViolation(v: { kind: 'name'|'default-export'|'export-name', expectedName?: string, foundNames?: string[] }, label: string, rel: string, connDir: string): string`
|
|
186
|
-
- **Повертає:** готовий текст повідомлення для `fail(...)`.
|
|
187
|
-
- **Поведінка за `kind`:**
|
|
188
|
-
- `'name'` — повідомлення про канон імен (`ql-<id>`, `pg-/mysql-/mssql-{read|write}[-<id>]`,
|
|
189
|
-
kebab-case `[a-z0-9-]`).
|
|
190
|
-
- `'default-export'` — заборонений `export default` у `connDir/`.
|
|
191
|
-
- інше (`'export-name'`) — очікувано `export const <expectedName>`; знайдені імена
|
|
192
|
-
показуються через кому, якщо `foundNames` непорожній, інакше тире.
|
|
193
|
-
|
|
194
|
-
### `checkProcessEnvUsage(absPackageRoot, sourcePaths, label, fail)`
|
|
195
|
-
|
|
196
|
-
- **Сигнатура:**
|
|
197
|
-
`async function checkProcessEnvUsage(absPackageRoot: string, sourcePaths: string[], label: string, fail: (msg: string) => void): Promise<number>`
|
|
198
|
-
- **Повертає:** кількість порушень.
|
|
199
|
-
- **Side effects:** `readFile`, `fail`.
|
|
200
|
-
- **Алгоритм:** для кожного файла читає вміст і викликає `findUncheckedProcessEnvInText`.
|
|
201
|
-
Залежно від `v.kind` формує різне повідомлення:
|
|
202
|
-
- `'process-env'` — пряме `process.env.X`: підказує замінити на `env` з
|
|
203
|
-
`@nitra/check-env` + `checkEnv(['X'])` або з `node:process` (опційно).
|
|
204
|
-
- інакше — `env.X` з `@nitra/check-env`, не закритий `checkEnv(['X'])` (або
|
|
205
|
-
`// @nitra/cursor ignore-next-line checkEnv`).
|
|
206
|
-
|
|
207
|
-
### `checkPromiseSetTimeoutPause(absPackageRoot, sourcePaths, label, fail)`
|
|
208
|
-
|
|
209
|
-
- **Сигнатура:**
|
|
210
|
-
`async function checkPromiseSetTimeoutPause(absPackageRoot: string, sourcePaths: string[], label: string, fail: (msg: string) => void): Promise<number>`
|
|
211
|
-
- **Повертає:** кількість порушень.
|
|
212
|
-
- **Side effects:** `readFile`, `fail`.
|
|
213
|
-
- **Алгоритм:** фільтрує файли через `isPromiseSetTimeoutScanSourceFile`, для решти
|
|
214
|
-
читає вміст і викликає `findPromiseSetTimeoutInText` — порушення друкуються з
|
|
215
|
-
підказкою «`await setTimeout(ms)` з `node:timers/promises`».
|
|
216
|
-
|
|
217
|
-
### `packageJsonHasViteDevDependency(pkgJson)`
|
|
218
|
-
|
|
219
|
-
- **Сигнатура:** `function packageJsonHasViteDevDependency(pkgJson: unknown): boolean`
|
|
220
|
-
- **Повертає:** `true`, якщо `pkgJson.devDependencies` — об'єкт і має ключ `'vite'`.
|
|
221
|
-
- **Side effects:** немає.
|
|
222
|
-
- **Семантика:** ідентично `packageJsonLacksViteDevDependency` з `auto-rules.mjs`, але
|
|
223
|
-
приймає вже розпарсений об'єкт (без I/O).
|
|
224
|
-
|
|
225
|
-
### `loadPackageJson(rootDir, cwd)`
|
|
226
|
-
|
|
227
|
-
- **Сигнатура:** `async function loadPackageJson(rootDir: string, cwd: string): Promise<unknown>`
|
|
228
|
-
- **Повертає:** розпарсений `package.json` пакета або `null`, якщо файла немає.
|
|
229
|
-
- **Side effects:** `existsSync`, `readFile`, `JSON.parse`.
|
|
230
|
-
- **Примітка:** заборону `@nitra/bunyan` / `bunyan` у `dependencies` / `devDependencies`
|
|
231
|
-
перенесено в Rego-пакет `npm/policy/js_run/package_json/`; тут залишилась лише AST-перевірка
|
|
232
|
-
імпортів.
|
|
233
|
-
|
|
234
|
-
### `checkOtelConfigmap(rootDir, passFn, cwd)`
|
|
235
|
-
|
|
236
|
-
- **Сигнатура:**
|
|
237
|
-
`function checkOtelConfigmap(rootDir: string, passFn: (msg: string) => void, cwd: string): void`
|
|
238
|
-
- **Повертає:** `void`.
|
|
239
|
-
- **Side effects:** `existsSync`, `passFn`.
|
|
240
|
-
- **Алгоритм:** якщо `<rootDir>/k8s/base/configmap.yaml` існує — друкує повідомлення про
|
|
241
|
-
факт наявності й нагадує, що структуру (OTEL-атрибути) перевіряє Rego через
|
|
242
|
-
`npx @nitra/cursor fix` → `js_run.configmap`.
|
|
243
|
-
|
|
244
|
-
## Залежності
|
|
245
|
-
|
|
246
|
-
### Node.js стандартна бібліотека
|
|
247
|
-
|
|
248
|
-
- `node:fs` — `existsSync`, `statSync` (синхронні перевірки наявності каталогу / файла).
|
|
249
|
-
- `node:fs/promises` — `readFile` (читання текстових файлів).
|
|
250
|
-
- `node:path` — `join`, `relative` (формування шляхів; `relPosix` додатково нормалізує).
|
|
251
|
-
|
|
252
|
-
### Локальні модулі (`../lib/`)
|
|
253
|
-
|
|
254
|
-
- `../lib/bunyan-imports.mjs` — `findBunyanImportsInText`, `isBunyanScanSourceFile`,
|
|
255
|
-
`shouldSkipFileForBunyanScan`.
|
|
256
|
-
- `../lib/check-env-scan.mjs` — `findUncheckedProcessEnvInText`, `isCheckEnvScanSourceFile`.
|
|
257
|
-
- `../lib/conn-file-rules.mjs` — `findConnFileRuleViolations`, `isConnFileRulesSourceFile`.
|
|
258
|
-
- `../lib/conn-imports-scan.mjs` — `findConnFactoryImportsInText`, `isConnImportsScanSourceFile`,
|
|
259
|
-
`isInsideConnDir`, `resolveConnDirFromPackageJson`.
|
|
260
|
-
- `../lib/promise-settimeout-scan.mjs` — `findPromiseSetTimeoutInText`,
|
|
261
|
-
`isPromiseSetTimeoutScanSourceFile`.
|
|
262
|
-
|
|
263
|
-
### Скрипти каркасу (`../../../scripts/`)
|
|
264
|
-
|
|
265
|
-
- `scripts/lib/check-reporter.mjs` — `createCheckReporter` (репортер `pass`/`fail` +
|
|
266
|
-
`getExitCode`).
|
|
267
|
-
- `scripts/lib/run-conftest-batch.mjs` — `runConftestBatch` (запуск `conftest` на наборі
|
|
268
|
-
файлів, повертає `violations[]`).
|
|
269
|
-
- `scripts/lib/load-cursor-config.mjs` — `loadCursorIgnorePaths` (читання списку шляхів
|
|
270
|
-
для виключення з обходу).
|
|
271
|
-
- `scripts/utils/walkDir.mjs` — `walkDir` (рекурсивний обхід каталогу з callback'ом і
|
|
272
|
-
списком ігнорувань).
|
|
273
|
-
- `scripts/lib/workspaces.mjs` — `getMonorepoPackageRootDirs` (перелік коренів
|
|
274
|
-
workspace-пакетів монорепо).
|
|
275
|
-
|
|
276
|
-
### Зовнішні залежності (через посередників)
|
|
277
|
-
|
|
278
|
-
- `conftest` — викликається з `runConftestBatch`; виконує Rego-політики, наприклад
|
|
279
|
-
`js_run.jsconfig` із `npm/rules/js-run/policy/jsconfig/`.
|
|
280
|
-
- `oxc-parser` — використовується в `bunyan-imports.mjs` для AST-сканування імпортів
|
|
281
|
-
(через залежність, не імпортується прямо тут).
|
|
282
|
-
|
|
283
|
-
## Потік виконання / Використання
|
|
284
|
-
|
|
285
|
-
### Точка входу
|
|
286
|
-
|
|
287
|
-
Модуль експортує лише `check(cwd?)`, яку викликає диспетчер правил (`@nitra/cursor check`)
|
|
288
|
-
для правила `js-run`. Очікуваний контракт — повернути exit-код для агрегації по всіх правилах.
|
|
289
|
-
|
|
290
|
-
### Високорівневий потік
|
|
291
|
-
|
|
292
|
-
```
|
|
293
|
-
check(cwd)
|
|
294
|
-
└─ createCheckReporter()
|
|
295
|
-
└─ getMonorepoPackageRootDirs(cwd) → roots
|
|
296
|
-
└─ workspaceRoots = roots.filter(r => r !== '.')
|
|
297
|
-
└─ [if empty] pass('немає workspace-пакетів') → return exitCode
|
|
298
|
-
└─ loadCursorIgnorePaths(cwd) → ignorePaths
|
|
299
|
-
└─ for each r ∈ workspaceRoots:
|
|
300
|
-
checkWorkspacePackage(r, ignorePaths, fail, pass, cwd)
|
|
301
|
-
├─ loadPackageJson(r, cwd)
|
|
302
|
-
├─ [if vite-frontend] passFn → return
|
|
303
|
-
├─ checkBackendJsconfigWhenSrcPresent(...)
|
|
304
|
-
│ ├─ backendPackageHasSrcDir → gate
|
|
305
|
-
│ ├─ [no jsconfig] fail
|
|
306
|
-
│ └─ runConftestBatch (Rego: js_run.jsconfig)
|
|
307
|
-
├─ checkBunyanImports(...)
|
|
308
|
-
│ ├─ walkDir → sourcePaths (фільтр bunyan-scan)
|
|
309
|
-
│ └─ for each → findBunyanImportsInText
|
|
310
|
-
├─ collectSourceFiles(...) → sourcePaths (фільтр check-env)
|
|
311
|
-
├─ checkConnImports(...)
|
|
312
|
-
│ └─ resolveConnDirFromPackageJson + findConnFactoryImportsInText
|
|
313
|
-
├─ checkConnFileNamingAndExports(...)
|
|
314
|
-
│ ├─ isConnFileToCheck
|
|
315
|
-
│ └─ findConnFileRuleViolations → formatConnFileViolation
|
|
316
|
-
├─ checkProcessEnvUsage(...)
|
|
317
|
-
│ └─ findUncheckedProcessEnvInText
|
|
318
|
-
├─ checkPromiseSetTimeoutPause(...)
|
|
319
|
-
│ └─ findPromiseSetTimeoutInText
|
|
320
|
-
└─ checkOtelConfigmap(...) [лише існування k8s/base/configmap.yaml]
|
|
321
|
-
└─ return reporter.getExitCode()
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
### Логіка пропусків (gate'и)
|
|
325
|
-
|
|
326
|
-
- **Кореневий `.`** workspace відфільтровується одразу.
|
|
327
|
-
- **Frontend (vite у `devDependencies`)** — увесь `js-run` пропускається на рівні
|
|
328
|
-
workspace.
|
|
329
|
-
- **`jsconfig.json`** — перевіряється лише там, де є `src/` каталог.
|
|
330
|
-
- **Conn-сканування** — імпорти `bun#SQL` / `mssql` / `@nitra/graphql-request#GraphQLClient`
|
|
331
|
-
перевіряються тільки **поза** каталогом `connDir` (а нейминг/експорти — тільки
|
|
332
|
-
всередині нього, окрім `index.*`).
|
|
333
|
-
- **Bunyan-сканування** — додатково керується `shouldSkipFileForBunyanScan` для специфічних
|
|
334
|
-
шляхів і `isBunyanScanSourceFile` для розширень.
|
|
335
|
-
- **`k8s/base/configmap.yaml`** — лише наявність; OTEL-атрибути перевіряє Rego.
|
|
336
|
-
|
|
337
|
-
### Як модуль інтегрується із суміжними частинами правила
|
|
338
|
-
|
|
339
|
-
- **AST-частина**: бере на себе крос-файлову й AST-логіку, яку складно виразити в Rego.
|
|
340
|
-
- **Per-document Rego**: `js_run.package_json` (bunyan/scripts.node), `js_run.configmap`
|
|
341
|
-
(OTEL), `js_run.jsconfig` (canonical `compilerOptions`/`include`).
|
|
342
|
-
- **JS-оркестрація Rego через `runConftestBatch`**: модуль викликає `conftest` лише там, де
|
|
343
|
-
попередній gate (наявність `src/` + наявність `jsconfig.json`) дозволяє це робити —
|
|
344
|
-
_Plan B_: Rego-authoritative, JS оркеструє per-package gate.
|
|
10
|
+
## Огляд
|
|
345
11
|
|
|
346
|
-
|
|
12
|
+
pgWriteContract перевіряє правила нейминга та експортів для файлів усередині `#conn/`.
|
|
13
|
+
check перевіряє правила js-run.mdc лише для workspace-пакетів.
|
|
347
14
|
|
|
348
|
-
|
|
349
|
-
import { check } from './runtime.mjs'
|
|
15
|
+
## Поведінка
|
|
350
16
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
```
|
|
17
|
+
pgWriteContract
|
|
18
|
+
Перевіряє відповідність правил нейминга та експортів для файлів усередині `#conn/`
|
|
354
19
|
|
|
355
|
-
|
|
20
|
+
check
|
|
21
|
+
Перевіряє відповідність правилам js-run.mdc лише для workspace-пакетів
|
|
356
22
|
|
|
357
|
-
|
|
358
|
-
- Відсутність помилок у під-перевірці → відповідне інформаційне `pass(...)`.
|
|
359
|
-
- Frontend-пакет (vite) ніколи не отримує жодного `fail` від цього модуля.
|
|
360
|
-
- Кореневий пакет монорепо ніколи не перевіряється цим модулем.
|
|
23
|
+
## Публічний API
|
|
361
24
|
|
|
362
|
-
|
|
25
|
+
- pgWriteContract — записує дані в контракт
|
|
26
|
+
- check — перевіряє дотримання правил js-run.mdc для пакетів у workspace
|
|
363
27
|
|
|
364
|
-
|
|
365
|
-
Якщо повністю відновлювати модуль за цим описом, відтворюються:
|
|
28
|
+
## Гарантії поведінки
|
|
366
29
|
|
|
367
|
-
-
|
|
368
|
-
-
|
|
369
|
-
-
|
|
370
|
-
-
|
|
371
|
-
|
|
372
|
-
- Gate `vite у devDependencies` → пропуск усього `js-run` для frontend-пакета.
|
|
373
|
-
- Gate `src/` для `jsconfig.json` та делегування структури до Rego `js_run.jsconfig`
|
|
374
|
-
через `runConftestBatch({ policyDirRel: 'js-run/jsconfig', namespace: 'js_run.jsconfig',
|
|
375
|
-
files: [jcPath] })`.
|
|
376
|
-
- Дев'ять допоміжних функцій (`backendPackageHasSrcDir`, `relPosix`, `checkBunyanImports`,
|
|
377
|
-
`collectSourceFiles`, `checkConnImports`, `checkConnFileNamingAndExports`,
|
|
378
|
-
`isConnFileToCheck`, `formatConnFileViolation`, `checkProcessEnvUsage`,
|
|
379
|
-
`checkPromiseSetTimeoutPause`, `packageJsonHasViteDevDependency`, `loadPackageJson`,
|
|
380
|
-
`checkOtelConfigmap`, `checkBackendJsconfigWhenSrcPresent`) із зазначеними сигнатурами,
|
|
381
|
-
параметрами й side effects.
|
|
382
|
-
- Перелік модулів-залежностей (`../lib/*`, `../../../scripts/lib/*`,
|
|
383
|
-
`../../../scripts/utils/walkDir.mjs`) і стандартних модулів Node.js (`node:fs`,
|
|
384
|
-
`node:fs/promises`, `node:path`).
|
|
385
|
-
- Інваріант, що `collectSourceFiles` використовує фільтр `isCheckEnvScanSourceFile`,
|
|
386
|
-
а інші скани мають свої внутрішні фільтри (`isConnImportsScanSourceFile`,
|
|
387
|
-
`isPromiseSetTimeoutScanSourceFile`).
|
|
388
|
-
- Формат повідомлень `fail(...)` із префіксом `[<pkg>] ` та номером рядка `${rel}:${v.line}`.
|
|
30
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
31
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
32
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
33
|
+
- Свідомо пропускає шляхи: `base/`.
|
|
34
|
+
- Не звертається до мережі.
|
package/rules/k8s/docs/fix.md
CHANGED
|
@@ -1,138 +1,33 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/rules/k8s/fix.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 38cf876b
|
|
5
|
+
score: 100
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
# fix.mjs
|
|
8
|
+
# fix.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
Файл
|
|
12
|
+
Файл надає механізми для виконання визначених правил. Виконання цих правил здійснюється через публічну функцію run. Виконання відбувається у режимі командного рядка.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. **Standalone mode** — якщо файл запущено напряму як CLI (`bun rules/k8s/fix.mjs`), він самостійно завантажує конфіг, застосовує whitelist, друкує summary та завершує процес із відповідним exit-code, тобто є повним еквівалентом команди `npx @nitra/cursor fix k8s`.
|
|
14
|
+
## Поведінка
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
1. Запуск правила.
|
|
17
|
+
* Виклик runStandardRule з контекстом.
|
|
18
|
+
* Повернення результату.
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
2. Запуск правила у режимі CLI.
|
|
21
|
+
* Виклик runRuleCli з директорією модуля.
|
|
22
|
+
* Вихід з процесом залежно від результату.
|
|
19
23
|
|
|
20
|
-
##
|
|
24
|
+
## Публічний API
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
| `run` | `(ctx?: RuleContext) => Promise<number>` | Запуск правила в **library mode**. Викликається верхньорівневим CLI під час оркестрації набору правил. |
|
|
26
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
27
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
25
28
|
|
|
26
|
-
|
|
29
|
+
## Гарантії поведінки
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
### `run(ctx)`
|
|
33
|
-
|
|
34
|
-
```js
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
|
-
export function run(ctx) {
|
|
39
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
40
|
-
}
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**Сигнатура:**
|
|
44
|
-
|
|
45
|
-
```ts
|
|
46
|
-
function run(ctx?: RuleContext): Promise<number>
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
**Параметри:**
|
|
50
|
-
|
|
51
|
-
- `ctx` _(опційно)_ — об'єкт контексту прогону типу `RuleContext` (тип реекспортується з `../../scripts/lib/run-standard-rule.mjs`). У контексті, як зазначено в JSDoc, може передаватися, зокрема, `walkCache` — спільний кеш обходу файлової системи між правилами, щоб не сканувати дерево заново для кожного правила в одній сесії. Якщо параметр не передано, `runStandardRule` працює без зовнішнього кешу.
|
|
52
|
-
|
|
53
|
-
**Повертає:**
|
|
54
|
-
|
|
55
|
-
- `Promise<number>` — exit-code результату прогону правила:
|
|
56
|
-
- `0` — OK (порушень немає);
|
|
57
|
-
- `1` — знайдено порушення (`runStandardRule` повертає `1`, коли хоча б одна перевірка дала falsy/негативний результат).
|
|
58
|
-
|
|
59
|
-
**Side effects:**
|
|
60
|
-
|
|
61
|
-
- Делегує всю роботу `runStandardRule`, який, своєю чергою:
|
|
62
|
-
- обходить файлову систему за `applies`-патернами правила;
|
|
63
|
-
- запускає підмодулі правила (`applies`, `JS-concerns`, `policy`, `mdc-refs`) — у послідовності, визначеній стандартним рушієм;
|
|
64
|
-
- пише діагностику/виводить порушення у stdout/stderr (точна форма залежить від рушія, не цього файлу).
|
|
65
|
-
- Сама функція `run` не торкається `process.exit`, `process.cwd` чи глобального стану — увесь побічний ефект інкапсульовано всередині `runStandardRule`.
|
|
66
|
-
|
|
67
|
-
**Чому передається `import.meta.dirname`:** це абсолютний шлях до каталогу `npm/rules/k8s/`, в якому лежить даний `fix.mjs`. `runStandardRule` за цим шляхом знаходить решту артефактів правила (наприклад, `k8s.mdc`, `applies.mjs`, `check-*.mjs`, `policy`-файли тощо), не вимагаючи від `fix.mjs` явно перераховувати, які саме перевірки треба виконати.
|
|
68
|
-
|
|
69
|
-
### Top-level standalone-блок
|
|
70
|
-
|
|
71
|
-
```js
|
|
72
|
-
if (isRunAsCli(import.meta.url)) {
|
|
73
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
74
|
-
}
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Призначення:** дозволити запускати правило окремо — `bun npm/rules/k8s/fix.mjs` — і отримати такий самий результат, як від `npx @nitra/cursor fix k8s` (із завантаженням конфігу, застосуванням whitelist та друком summary).
|
|
78
|
-
|
|
79
|
-
**Поведінка:**
|
|
80
|
-
|
|
81
|
-
- `isRunAsCli(import.meta.url)` повертає `true`, якщо поточний файл є entry-point процесу (а не імпортований модуль). Якщо це бібліотечний імпорт — блок не виконується, побічних ефектів немає.
|
|
82
|
-
- `runRuleCli(import.meta.dirname)` — повний CLI-цикл одного правила: завантаження конфігу проєкту, фільтр whitelist, виклик `run`-логіки, друк підсумкового summary; повертає `Promise<number>` — exit-code.
|
|
83
|
-
- `process.exit(...)` примусово завершує процес із цим exit-code, щоб CI/IDE могли коректно проінтерпретувати результат прогону.
|
|
84
|
-
|
|
85
|
-
**Top-level `await`:** доступний у файлі завдяки тому, що `.mjs` є ES-модулем — це обов'язкова умова для коректної роботи `await runRuleCli(...)` поза `async`-функцією.
|
|
86
|
-
|
|
87
|
-
**ESLint-директива:** коментар `// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit` свідомо вимикає правила, що забороняють `process.exit`, тому що standalone entry-point **повинен** повертати exit-code (це і пояснює коментар-`-- ...` після назв правил).
|
|
88
|
-
|
|
89
|
-
## Залежності
|
|
90
|
-
|
|
91
|
-
### Внутрішні
|
|
92
|
-
|
|
93
|
-
- `../../scripts/lib/run-rule-cli.mjs` (`npm/scripts/lib/run-rule-cli.mjs`) — імпортуються два named-експорти:
|
|
94
|
-
- `isRunAsCli(metaUrl)` — детектор того, чи запущений файл як CLI-entry, а не як імпортований модуль (стандартний ESM-патерн «main module detection» через `import.meta.url`);
|
|
95
|
-
- `runRuleCli(ruleDir)` — повний цикл standalone-прогону одного правила (config-loading + whitelist + виклик `run` + summary).
|
|
96
|
-
- `../../scripts/lib/run-standard-rule.mjs` (`npm/scripts/lib/run-standard-rule.mjs`) — імпортується:
|
|
97
|
-
- `runStandardRule(ruleDir, ctx?)` — універсальний рушій «стандартного» правила, що знаходить за `ruleDir` усі артефакти (`applies`, `JS-concerns`, `policy`, `mdc-refs`) і запускає їх у правильному порядку;
|
|
98
|
-
- реекспортує тип `RuleContext` (використовується у JSDoc `@param`).
|
|
99
|
-
|
|
100
|
-
### Зовнішні
|
|
101
|
-
|
|
102
|
-
- Глобальні Node-runtime API: `process.exit` (умовний виклик), `import.meta.dirname`, `import.meta.url`. Окремих npm-залежностей цей файл не має.
|
|
103
|
-
|
|
104
|
-
## Потік виконання / Використання
|
|
105
|
-
|
|
106
|
-
### Сценарій 1. Library mode (типове використання)
|
|
107
|
-
|
|
108
|
-
1. Верхньорівневий CLI-оркестратор `@nitra/cursor` (наприклад, команда `fix`) збирає список активних правил.
|
|
109
|
-
2. Для правила `k8s` він робить динамічний імпорт цього файлу (`import('npm/rules/k8s/fix.mjs')`).
|
|
110
|
-
3. Оркестратор формує спільний `ctx: RuleContext` (зокрема `walkCache`, який буде поділено між правилами однієї сесії) і викликає `await mod.run(ctx)`.
|
|
111
|
-
4. `run` делегує виклик `runStandardRule(import.meta.dirname, ctx)`, який:
|
|
112
|
-
- читає артефакти правила з каталогу `npm/rules/k8s/`;
|
|
113
|
-
- обходить FS відповідно до `applies`-патернів (використовуючи `ctx.walkCache`, якщо переданий);
|
|
114
|
-
- послідовно виконує перевірки `applies → JS-concerns → policy → mdc-refs`;
|
|
115
|
-
- повертає `0` (OK) або `1` (порушення).
|
|
116
|
-
5. Оркестратор агрегує exit-коди з усіх правил у фінальний exit-code сесії.
|
|
117
|
-
|
|
118
|
-
### Сценарій 2. Standalone mode (запуск одного правила вручну)
|
|
119
|
-
|
|
120
|
-
1. Користувач запускає `bun npm/rules/k8s/fix.mjs` (або еквівалент через інший Node-runtime з підтримкою `import.meta.dirname`).
|
|
121
|
-
2. ESM-завантажувач виконує файл як entry-point: визначення `run` потрапляє у scope модуля, але оркестратор ззовні його не викликає.
|
|
122
|
-
3. Виконується top-level `if (isRunAsCli(import.meta.url))` — умова `true`, оскільки `import.meta.url` збігається з entry-point процесу.
|
|
123
|
-
4. Викликається `await runRuleCli(import.meta.dirname)`:
|
|
124
|
-
- підвантажується конфіг проєкту;
|
|
125
|
-
- застосовується whitelist (якщо налаштований);
|
|
126
|
-
- всередині `runRuleCli` запускається та сама логіка правила (через ту саму експортовану функцію `run` / `runStandardRule`), що й у library mode;
|
|
127
|
-
- друкується summary з кількістю перевірених файлів і знайдених порушень.
|
|
128
|
-
5. Отриманий `exit-code` передається в `process.exit(...)` — процес завершується із цим кодом, що дозволяє CI/IDE коректно реагувати на результат.
|
|
129
|
-
|
|
130
|
-
### Сценарій 3. Імпорт як модуля без виклику `run`
|
|
131
|
-
|
|
132
|
-
Якщо файл імпортується суто для інтроспекції (`import * as fixK8s from '.../k8s/fix.mjs'`), `isRunAsCli(import.meta.url)` поверне `false` (`import.meta.url` модуля не співпаде з URL entry-point процесу), і standalone-блок не виконається. Жодних побічних ефектів імпорт не має — це **безпечно** для тулзів типу docgen чи статичного аналізу.
|
|
133
|
-
|
|
134
|
-
### Замітки про шаблон
|
|
135
|
-
|
|
136
|
-
- Файл є **взаємозамінним** із аналогічними `fix.mjs` у сусідніх каталогах `npm/rules/<id>/` — відрізняється лише розташуванням (а отже — `import.meta.dirname`), і завдяки цьому той самий рушій `runStandardRule` обслуговує всі правила без копіювання логіки.
|
|
137
|
-
- Жодна k8s-специфічна логіка тут **не** жорстко закодована — вона лежить у сусідніх файлах правила (`k8s.mdc`, `applies.mjs`, `check-*.mjs`, `policy`-артефакти), які знаходить `runStandardRule` за каталогом.
|
|
138
|
-
- Для додавання нового правила достатньо створити каталог `npm/rules/<new-id>/` і покласти туди такий самий `fix.mjs` — без жодних модифікацій (за умови, що структура артефактів стандартна).
|
|
31
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
32
|
+
- Кешує результати в межах одного прогону.
|
|
33
|
+
- Не звертається до мережі.
|