@nitra/cursor 5.3.3 → 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 +17 -0
- package/bin/n-cursor.js +43 -22
- package/lib/docs/llm.md +23 -12
- 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/rules/doc-files/js/docs/docgen-extract-anchors.md +45 -0
- package/rules/doc-files/js/docs/docgen-extract.md +39 -0
- package/rules/doc-files/js/docs/docgen-files-batch.md +35 -0
- package/rules/doc-files/js/docs/docgen-gen.md +46 -0
- package/rules/doc-files/js/docs/docgen-ignore.md +37 -0
- 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-0012.md +5 -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-extract-anchors.md +0 -27
- package/skills/doc-files/js/docs/docgen-extract.md +0 -29
- package/skills/doc-files/js/docs/docgen-files-batch.md +0 -25
- package/skills/doc-files/js/docs/docgen-gen.md +0 -30
- 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,348 +1,51 @@
|
|
|
1
|
-
# tooling.mjs
|
|
2
|
-
|
|
3
|
-
## Огляд
|
|
4
|
-
|
|
5
|
-
Модуль `tooling.mjs` реалізує перевірку (check-частину) правила **`js-lint.mdc`** для проєктів-споживачів пакета `@nitra/cursor`. Він гарантує, що репозиторій налаштований на канонічний JS-toolchain Nitra:
|
|
6
|
-
|
|
7
|
-
- наявність та коректний вміст **flat ESLint config** (`eslint.config.js` або `eslint.config.mjs`) з виклику `getConfig` із `@nitra/eslint-config` та `ignores` для `**/auto-imports.d.ts`;
|
|
8
|
-
- **`.oxlintrc.json`** має збігатися з канонічним JSON у пакеті (`npm/rules/js-lint/js/data/tooling/oxlint-canonical.json`) — `plugins`, `jsPlugins`, `categories`, усі правила з канону, `settings`, `env`, `globals`, `ignorePatterns`; додаткові записи дозволені лише у блоці `rules`;
|
|
9
|
-
- кожен workspace-`package.json` має `"type": "module"`, `engines.node >= 24` та `engines.bun >= 1.3`;
|
|
10
|
-
- існує workflow `.github/workflows/lint-js.yml` (структуру валідує Rego-policy `js_lint.lint_js_yml`), а `.github/workflows/lint.yml` (якщо є) **не дублює** кроки `bunx oxlint` / `bunx eslint` / `jscpd`;
|
|
11
|
-
- існує `knip.json` (якщо відсутній — копіюється канонічний baseline з пакета);
|
|
12
|
-
- у репозиторії **немає** застарілих legacy-конфігів ESLint (`.eslintrc`, `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml`).
|
|
13
|
-
|
|
14
|
-
Per-document вимоги (`lint-js` script, мінімальна версія `@nitra/eslint-config ≥ 3.10.0`, root `engines`, `.jscpd.json`, `.vscode/extensions.json`, структура `lint-js.yml`) вже **не** реалізуються тут — їх валідують Rego-policy-пакети `js_lint.*` (`npm/policy/js_lint/package_json/`, `npm/policy/js_lint/lint_js_yml/`). Це усуває дублювання істини між JS-перевіркою та Rego-політиками.
|
|
15
|
-
|
|
16
|
-
Модуль використовує спільний `createCheckReporter` зі скриптів пакета: збирає `pass` / `fail`-повідомлення та повертає числовий exit-код (0 — OK, 1 — є проблеми).
|
|
17
|
-
|
|
18
|
-
## Експорти / API
|
|
19
|
-
|
|
20
|
-
| Експорт | Тип | Призначення |
|
|
21
|
-
| ------------------------------------------------ | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
22
|
-
| `OXLINT_CANONICAL_JSON_PATH` | `string` (named const) | Абсолютний шлях до канонічного `oxlint-canonical.json` у цьому пакеті (`<dirname>/data/tooling/oxlint-canonical.json`). Використовується перевіркою та тестами. |
|
|
23
|
-
| `KNIP_CANONICAL_JSON_PATH` | `string` (named const) | Абсолютний шлях до канонічного `knip-canonical.json` у цьому пакеті. Копіюється у корінь проєкту-споживача, якщо `knip.json` відсутній. |
|
|
24
|
-
| `verifyOxlintRcAgainstCanonical(cfg, canonical)` | `function` (named export) | Чиста функція звірення розпарсеного `.oxlintrc.json` із канонічним JSON. Повертає `{ ok: boolean, failures: string[] }`. |
|
|
25
|
-
| `check(cwd?)` | `async function` (named export) | Точка входу: запускає всі under-the-hood перевірки і повертає `Promise<number>` (0 — все добре, 1 — є fail). |
|
|
26
|
-
|
|
27
|
-
Усі решта функцій (`deepEqualOxlintCanonical`, `asRecordOrEmpty`, `compareOxlintRules`, `compareOxlintIgnorePatterns`, `checkEslintConfig`, `checkPackageJsonTypeModule`, `checkWorkspacePackages`, `checkEnginesNode`, `checkEnginesBun`, `checkPackageJsonJsLint`, `checkOxlintRc`, `checkLintJsWorkflows`, `checkKnipConfig`) — **module-private** (не експортуються).
|
|
28
|
-
|
|
29
|
-
## Функції
|
|
30
|
-
|
|
31
|
-
### `deepEqualOxlintCanonical(actual, expected)`
|
|
32
|
-
|
|
33
|
-
**Сигнатура:** `function deepEqualOxlintCanonical(actual: unknown, expected: unknown): boolean`
|
|
34
|
-
|
|
35
|
-
**Параметри:**
|
|
36
|
-
|
|
37
|
-
- `actual` — значення з `.oxlintrc.json` (будь-який тип);
|
|
38
|
-
- `expected` — еталонне значення з канону.
|
|
39
|
-
|
|
40
|
-
**Повертає:** `true`, якщо `actual` повністю збігається з `expected` за правилами канону:
|
|
41
|
-
|
|
42
|
-
- примітиви — `===`;
|
|
43
|
-
- масиви — однакові за `JSON.stringify` (тобто **порядок** теж важливий);
|
|
44
|
-
- об’єкти — **той самий набір ключів** (`expKeys.length === actKeys.length` і всі ключі канону присутні в actual) та рекурсивно рівні значення.
|
|
45
|
-
|
|
46
|
-
**Side effects:** немає (чиста функція).
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
### `asRecordOrEmpty(v)`
|
|
51
|
-
|
|
52
|
-
**Сигнатура:** `function asRecordOrEmpty(v: unknown): Record<string, unknown>`
|
|
53
|
-
|
|
54
|
-
**Параметри:**
|
|
55
|
-
|
|
56
|
-
- `v` — будь-яке значення.
|
|
57
|
-
|
|
58
|
-
**Повертає:** саме значення (із cast-коментарем), якщо це plain-object (`typeof v === 'object'`, не `null`, не масив); інакше — `{}`.
|
|
59
|
-
|
|
60
|
-
**Side effects:** немає.
|
|
61
|
-
|
|
62
|
-
---
|
|
63
|
-
|
|
64
|
-
### `compareOxlintRules(expected, actual, failures)`
|
|
65
|
-
|
|
66
|
-
**Сигнатура:** `function compareOxlintRules(expected: unknown, actual: unknown, failures: string[]): void`
|
|
67
|
-
|
|
68
|
-
**Параметри:**
|
|
69
|
-
|
|
70
|
-
- `expected` — канонічний об’єкт `rules`;
|
|
71
|
-
- `actual` — значення `rules` з поточного `.oxlintrc.json`;
|
|
72
|
-
- `failures` — буфер-масив, у який функція **дописує** повідомлення про невідповідності.
|
|
73
|
-
|
|
74
|
-
**Поведінка:** ітерує по ключах канону; якщо `actual[ruleKey] !== expected[ruleKey]` (строге `!==` — отже об’єктні значення правил мають бути тим самим референсом, що рідко зустрічається — на практиці значення правил у oxlint це числа / рядки / прості масиви), додає повідомлення у форматі:
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
.oxlintrc.json: rules["<key>"] очікується <expected>, зараз <actual>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Додаткові ключі правил у `actual` **дозволені** (не повідомляються).
|
|
81
|
-
|
|
82
|
-
**Повертає:** `undefined`.
|
|
83
|
-
|
|
84
|
-
**Side effects:** мутує `failures`.
|
|
85
|
-
|
|
86
|
-
---
|
|
87
|
-
|
|
88
|
-
### `compareOxlintIgnorePatterns(expected, actual, failures)`
|
|
89
|
-
|
|
90
|
-
**Сигнатура:** `function compareOxlintIgnorePatterns(expected: unknown, actual: unknown, failures: string[]): void`
|
|
91
|
-
|
|
92
|
-
**Параметри:**
|
|
93
|
-
|
|
94
|
-
- `expected` — канонічний масив `ignorePatterns`;
|
|
95
|
-
- `actual` — поточний масив `ignorePatterns`;
|
|
96
|
-
- `failures` — буфер для повідомлень.
|
|
97
|
-
|
|
98
|
-
**Поведінка:**
|
|
99
|
-
|
|
100
|
-
- якщо `expected` не є масивом — функція мовчки виходить (канон не задає очікувань);
|
|
101
|
-
- якщо `actual` не є масивом — додає повідомлення про обов’язковість масиву;
|
|
102
|
-
- порівнює як **підмножину**: усі канонічні патерни мають бути в `actual` (через `Set`); відсутні патерни перелічуються одним повідомленням. Додаткові локальні патерни **дозволені**.
|
|
103
|
-
|
|
104
|
-
**Повертає:** `undefined`.
|
|
105
|
-
|
|
106
|
-
**Side effects:** мутує `failures`.
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
### `verifyOxlintRcAgainstCanonical(cfg, canonical)` _(експортовано)_
|
|
111
|
-
|
|
112
|
-
**Сигнатура:** `function verifyOxlintRcAgainstCanonical(cfg: unknown, canonical: unknown): { ok: boolean, failures: string[] }`
|
|
113
|
-
|
|
114
|
-
**Параметри:**
|
|
115
|
-
|
|
116
|
-
- `cfg` — розпарсений корінь `.oxlintrc.json`;
|
|
117
|
-
- `canonical` — розпарсений `oxlint-canonical.json`.
|
|
118
|
-
|
|
119
|
-
**Поведінка:**
|
|
120
|
-
|
|
121
|
-
1. Якщо `cfg` чи `canonical` не є plain-object — повертає `ok: false` з відповідним повідомленням (для `cfg` — про невалідний корінь; для `canonical` — як «внутрішня помилка»).
|
|
122
|
-
2. Для кожного ключа канону:
|
|
123
|
-
- `rules` → делегує `compareOxlintRules`;
|
|
124
|
-
- `ignorePatterns` → делегує `compareOxlintIgnorePatterns`;
|
|
125
|
-
- решта ключів → перевіряється через `deepEqualOxlintCanonical`; при невідповідності в `failures` додається повідомлення, що поле має збігатися з каноном пакета `@nitra/cursor`.
|
|
126
|
-
3. Повертає `{ ok: failures.length === 0, failures }`.
|
|
127
|
-
|
|
128
|
-
**Повертає:** результат-об’єкт із прапором `ok` і масивом fail-повідомлень для подальшого репортинга.
|
|
129
|
-
|
|
130
|
-
**Side effects:** немає (чиста функція; працює з аргументами, не читає файли).
|
|
131
|
-
|
|
132
|
-
---
|
|
133
|
-
|
|
134
|
-
### `checkEslintConfig(passFn, failFn, cwd)`
|
|
135
|
-
|
|
136
|
-
**Сигнатура:** `async function checkEslintConfig(passFn: (msg:string)=>void, failFn: (msg:string)=>void, cwd: string): Promise<void>`
|
|
137
|
-
|
|
138
|
-
**Параметри:**
|
|
139
|
-
|
|
140
|
-
- `passFn` — колбек успіху;
|
|
141
|
-
- `failFn` — колбек помилки;
|
|
142
|
-
- `cwd` — корінь репозиторію.
|
|
143
|
-
|
|
144
|
-
**Поведінка:**
|
|
145
|
-
|
|
146
|
-
- шукає `eslint.config.js`, потім `eslint.config.mjs`; якщо жодного — fail і ранній вихід;
|
|
147
|
-
- читає вміст знайденого файла як `utf8` і застосовує три суто **текстові** перевірки наявності підрядків:
|
|
148
|
-
1. `getConfig` — обов’язковий виклик;
|
|
149
|
-
2. `@nitra/eslint-config` — обов’язковий імпорт;
|
|
150
|
-
3. `**/auto-imports.d.ts` — обов’язковий запис у `ignores`.
|
|
151
|
-
|
|
152
|
-
**Повертає:** `Promise<void>`.
|
|
153
|
-
|
|
154
|
-
**Side effects:** читає файли з ФС (`existsSync`, `readFile`); викликає `passFn`/`failFn`.
|
|
155
|
-
|
|
156
1
|
---
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
**Поведінка:** якщо `pkg.type === 'module'` → `passFn`; інакше → `failFn` з вимогою додати поле.
|
|
163
|
-
|
|
164
|
-
**Side effects:** виклики переданих колбеків.
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
### `checkWorkspacePackages(workspaces, passFn, failFn, cwd)`
|
|
169
|
-
|
|
170
|
-
**Сигнатура:** `async function checkWorkspacePackages(workspaces: unknown[], passFn, failFn, cwd: string): Promise<void>`
|
|
171
|
-
|
|
172
|
-
**Поведінка:** для кожного запису workspaces:
|
|
173
|
-
|
|
174
|
-
- будує шлях `<ws>/package.json`;
|
|
175
|
-
- якщо файл існує — читає та парсить JSON; запускає послідовно `checkPackageJsonTypeModule`, `checkEnginesNode`, `checkEnginesBun`.
|
|
176
|
-
|
|
177
|
-
**Side effects:** читання ФС, виклики колбеків.
|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
### `checkEnginesNode(label, pkg, passFn, failFn)`
|
|
182
|
-
|
|
183
|
-
**Сигнатура:** `function checkEnginesNode(label: string, pkg: { engines?: { node?: string } }, passFn, failFn): void`
|
|
184
|
-
|
|
185
|
-
**Поведінка:** дістає `pkg.engines?.node`; через регекс `NON_DIGITS_RE = /\D+/u` бере **перший** числовий токен (наприклад, з `">=24"` → `"24"`); якщо це число ≥ 24 → pass, інакше → fail; якщо поле відсутнє → fail з пропозицією додати `"engines": { "node": ">=24" }`.
|
|
186
|
-
|
|
187
|
-
**Side effects:** виклики колбеків.
|
|
188
|
-
|
|
189
|
-
---
|
|
190
|
-
|
|
191
|
-
### `checkEnginesBun(label, pkg, passFn, failFn)`
|
|
192
|
-
|
|
193
|
-
**Сигнатура:** `function checkEnginesBun(label: string, pkg: { engines?: { bun?: string } }, passFn, failFn): void`
|
|
194
|
-
|
|
195
|
-
**Поведінка:** дістає `pkg.engines?.bun`; розбиває рядок по `NON_DIGITS_RE`, фільтрує порожні токени, бере перші два як `[major, minor]`; pass якщо `major > 1` або `major === 1 && minor >= 3`; інакше fail; відсутнє поле → fail з пропозицією додати `"engines": { "bun": ">=1.3" }`.
|
|
196
|
-
|
|
197
|
-
**Side effects:** виклики колбеків.
|
|
198
|
-
|
|
199
|
-
---
|
|
200
|
-
|
|
201
|
-
### `checkPackageJsonJsLint(passFn, failFn, cwd)`
|
|
202
|
-
|
|
203
|
-
**Сигнатура:** `async function checkPackageJsonJsLint(passFn, failFn, cwd: string): Promise<void>`
|
|
204
|
-
|
|
205
|
-
**Поведінка:** читає кореневий `package.json` (якщо відсутній — мовчки виходить); бере поле `workspaces` (масив або `[]`) і делегує `checkWorkspacePackages`. Кореневий `package.json` тут **не** валідується — це робить Rego-policy `npm/policy/js_lint/package_json/`.
|
|
206
|
-
|
|
207
|
-
**Side effects:** читання ФС, виклики колбеків.
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
### `checkOxlintRc(passFn, failFn, cwd)`
|
|
212
|
-
|
|
213
|
-
**Сигнатура:** `async function checkOxlintRc(passFn, failFn, cwd: string): Promise<void>`
|
|
214
|
-
|
|
215
|
-
**Поведінка:**
|
|
216
|
-
|
|
217
|
-
1. Якщо `.oxlintrc.json` відсутній → fail і ранній вихід.
|
|
218
|
-
2. Спроба JSON-парсингу; при помилці → fail про невалідний JSON.
|
|
219
|
-
3. Pass-повідомлення про наявність файла.
|
|
220
|
-
4. Читає канонічний `oxlint-canonical.json` (шлях `OXLINT_CANONICAL_JSON_PATH`); при помилці → fail-повідомлення «внутрішня помилка».
|
|
221
|
-
5. Викликає `verifyOxlintRcAgainstCanonical(oxCfg, canonical)`; pass якщо `ok`, інакше — повторно викликає `failFn` для кожного повідомлення зі списку `failures`.
|
|
222
|
-
|
|
223
|
-
**Side effects:** читання ФС, виклики колбеків.
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
### `checkLintJsWorkflows(passFn, failFn, cwd)`
|
|
228
|
-
|
|
229
|
-
**Сигнатура:** `async function checkLintJsWorkflows(passFn, failFn, cwd: string): Promise<void>`
|
|
230
|
-
|
|
231
|
-
**Поведінка:**
|
|
232
|
-
|
|
233
|
-
- перевіряє існування `.github/workflows/lint-js.yml` → pass з нагадуванням, що структуру валідує Rego (`js_lint.lint_js_yml`); відсутність → fail;
|
|
234
|
-
- якщо існує `.github/workflows/lint.yml` — читає його як текст і перевіряє, що він **не містить одночасно** трьох підрядків `bunx oxlint`, `bunx eslint`, `jscpd`. Якщо містить — fail (дубль кроків JS-лінта), інакше — pass.
|
|
235
|
-
|
|
236
|
-
**Side effects:** читання ФС, виклики колбеків.
|
|
237
|
-
|
|
238
|
-
---
|
|
239
|
-
|
|
240
|
-
### `checkKnipConfig(passFn, failFn, cwd)`
|
|
241
|
-
|
|
242
|
-
**Сигнатура:** `async function checkKnipConfig(passFn, failFn, cwd: string): Promise<void>`
|
|
243
|
-
|
|
244
|
-
**Поведінка:**
|
|
245
|
-
|
|
246
|
-
- якщо `knip.json` існує у корені — pass і вихід;
|
|
247
|
-
- якщо відсутній і канонічний шаблон `KNIP_CANONICAL_JSON_PATH` теж недоступний (`existsSync` повертає false) — fail з пропозицією перевстановити `@nitra/cursor`;
|
|
248
|
-
- інакше — **копіює** канонічний JSON у `cwd/knip.json` через `copyFile` і повідомляє pass.
|
|
249
|
-
|
|
250
|
-
**Side effects:** читання ФС, **запис** нового файла `knip.json`, виклики колбеків. Це єдина функція модуля з write-side-effect.
|
|
251
|
-
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/js-lint/js/tooling.mjs
|
|
4
|
+
crc: e847996e
|
|
5
|
+
score: 80
|
|
252
6
|
---
|
|
253
7
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
**Сигнатура:** `async function check(cwd?: string): Promise<number>` (за замовчуванням `cwd = process.cwd()`).
|
|
257
|
-
|
|
258
|
-
**Поведінка:**
|
|
259
|
-
|
|
260
|
-
1. Створює репортер через `createCheckReporter()` і отримує `pass` / `fail` колбеки.
|
|
261
|
-
2. Послідовно `await`-ить:
|
|
262
|
-
- `checkEslintConfig` — flat-config;
|
|
263
|
-
- `checkPackageJsonJsLint` — workspace-`package.json`;
|
|
264
|
-
- `checkOxlintRc` — `.oxlintrc.json` vs canonical;
|
|
265
|
-
- `checkLintJsWorkflows` — `lint-js.yml` + дубль у `lint.yml`;
|
|
266
|
-
- `checkKnipConfig` — `knip.json` (з можливим створенням).
|
|
267
|
-
3. Перевіряє наявність legacy-файлів у списку `['.eslintrc', '.eslintrc.js', '.eslintrc.json', '.eslintrc.yml']`; для кожного знайденого — `fail`.
|
|
268
|
-
4. Повертає `reporter.getExitCode()` — `0` якщо не було жодного `fail`, інакше `1`.
|
|
269
|
-
|
|
270
|
-
**Повертає:** `Promise<number>` — exit-код для CLI.
|
|
271
|
-
|
|
272
|
-
**Side effects:** усі ефекти із дочірніх функцій (читання ФС, можливий запис `knip.json`, виведення pass/fail через репортер).
|
|
273
|
-
|
|
274
|
-
## Залежності
|
|
275
|
-
|
|
276
|
-
### Стандартна бібліотека Node.js
|
|
277
|
-
|
|
278
|
-
- `node:fs` → `existsSync` — синхронна перевірка наявності файлів.
|
|
279
|
-
- `node:fs/promises` → `copyFile`, `readFile` — асинхронні файлові операції.
|
|
280
|
-
- `node:path` → `dirname`, `join` — побудова шляхів.
|
|
281
|
-
- `node:url` → `fileURLToPath` — перетворення `import.meta.url` для отримання абсолютної директорії модуля.
|
|
282
|
-
|
|
283
|
-
### Внутрішні
|
|
284
|
-
|
|
285
|
-
- `../../../scripts/lib/check-reporter.mjs` → `createCheckReporter` — фабрика репортера зі стандартними `pass` / `fail` колбеками та методом `getExitCode()`.
|
|
286
|
-
|
|
287
|
-
### Канонічні артефакти даних (читаються/копіюються, але не імпортуються як JS-модулі)
|
|
288
|
-
|
|
289
|
-
- `data/tooling/oxlint-canonical.json` — еталон `.oxlintrc.json`.
|
|
290
|
-
- `data/tooling/knip-canonical.json` — baseline для `knip.json` (копіюється у проєкт-споживач).
|
|
291
|
-
|
|
292
|
-
### Зовнішні
|
|
293
|
-
|
|
294
|
-
Жодних рантайм-залежностей з `node_modules` модуль не використовує. (Перевірки на наявність `@nitra/eslint-config` виконуються **текстово** як пошук підрядка у файлі ESLint-конфіга.)
|
|
295
|
-
|
|
296
|
-
## Потік виконання / Використання
|
|
8
|
+
# tooling.mjs
|
|
297
9
|
|
|
298
|
-
|
|
10
|
+
## Огляд
|
|
299
11
|
|
|
300
|
-
|
|
12
|
+
OXLINT_CANONICAL_JSON_PATH
|
|
13
|
+
Повертає шлях до канонічного JSON-файлу oxlint у пакету
|
|
301
14
|
|
|
302
|
-
|
|
303
|
-
|
|
15
|
+
KNIP_CANONICAL_JSON_PATH
|
|
16
|
+
Повертає шлях до канонічного JSON-файлу knip у пакету
|
|
304
17
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
```
|
|
18
|
+
verifyOxlintRcAgainstCanonical
|
|
19
|
+
Звіряє блок rules з `.oxlintrc.json` проти канону пакета @nitra/cursor
|
|
308
20
|
|
|
309
|
-
|
|
21
|
+
check
|
|
22
|
+
Перевіряє конфігурацію проєкту відповідно до правил js-lint.mdc
|
|
310
23
|
|
|
311
|
-
|
|
24
|
+
## Поведінка
|
|
312
25
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
3. **.oxlintrc.json** → читаємо JSON, парсимо канон із пакета, повне дерев’яне порівняння через `verifyOxlintRcAgainstCanonical` (особливі правила для `rules` і `ignorePatterns`).
|
|
316
|
-
4. **GitHub workflows** → перевіряємо існування `lint-js.yml`; перевіряємо, що `lint.yml` не дублює `bunx oxlint` + `bunx eslint` + `jscpd`.
|
|
317
|
-
5. **knip.json** → якщо відсутній, копіюємо канонічний baseline; інакше — лише фіксуємо наявність.
|
|
318
|
-
6. **Legacy ESLint configs** → fail для будь-якого з `.eslintrc`, `.eslintrc.js`, `.eslintrc.json`, `.eslintrc.yml` у корені.
|
|
319
|
-
7. Повертаємо `0` або `1` через репортер.
|
|
26
|
+
OXLINT_CANONICAL_JSON_PATH
|
|
27
|
+
Шлях до канонічного oxlint JSON у цьому пакеті
|
|
320
28
|
|
|
321
|
-
|
|
29
|
+
KNIP_CANONICAL_JSON_PATH
|
|
30
|
+
Шлях до канонічного knip JSON у цьому пакеті
|
|
322
31
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
| Наявність `eslint.config.{js,mjs}` + ключові підрядки | **тут** (`checkEslintConfig`) |
|
|
326
|
-
| `type: "module"`, `engines.{node,bun}` у workspace-пакетах | **тут** (`checkWorkspacePackages`) |
|
|
327
|
-
| Той самий набір полів у кореневому `package.json`, мінімальна версія `@nitra/eslint-config`, `lint-js`-script, `prettier`, `@nitra/prettier-config` | Rego: `npm/policy/js_lint/package_json/`, `npm/policy/text/package_json/` |
|
|
328
|
-
| Збіг `.oxlintrc.json` з канонічним JSON | **тут** (`checkOxlintRc` + `verifyOxlintRcAgainstCanonical`) |
|
|
329
|
-
| Наявність `lint-js.yml`, заборона дубля у `lint.yml` | **тут** (`checkLintJsWorkflows`) |
|
|
330
|
-
| Структура `lint-js.yml` (`actions/checkout@v6`, `persist-credentials: false`, `setup-bun-deps`, заборона `--fix`) | Rego: `npm/policy/js_lint/lint_js_yml/` |
|
|
331
|
-
| Bootstrap `knip.json` (копіювання канону) | **тут** (`checkKnipConfig`) |
|
|
332
|
-
| Заборона legacy `.eslintrc*` | **тут** (`check`, фінальний цикл) |
|
|
32
|
+
verifyOxlintRcAgainstCanonical
|
|
33
|
+
Звіряє блок rules з `.oxlintrc.json` проти канону пакета @nitra/cursor
|
|
333
34
|
|
|
334
|
-
|
|
35
|
+
check
|
|
36
|
+
Перевіряє конфігурацію проєкту відповідно до правил js-lint.mdc
|
|
335
37
|
|
|
336
|
-
|
|
337
|
-
- Винятки JSON-парсингу `.oxlintrc.json` ловляться локально та трансформуються у fail-повідомлення; невдала зчитка канону також не кидає виняток назовні (стає «внутрішня помилка»). Інші помилки (наприклад, `JSON.parse` для workspace-`package.json`) **не** ловляться і прокидаються через `Promise<number>` як rejection — це сигналізує про серйозну поломку (битий JSON у відомому файлі).
|
|
38
|
+
## Публічний API
|
|
338
39
|
|
|
339
|
-
|
|
40
|
+
OXLINT_CANONICAL_JSON_PATH — Шлях до канонічного oxlint JSON у пакету (для перевірки та тестів)
|
|
41
|
+
KNIP_CANONICAL_JSON_PATH — Шлях до канонічного knip JSON у пакету (копіюється у корінь проєкту-споживача, якщо відсутній)
|
|
42
|
+
verifyOxlintRcAgainstCanonical — Порівнює `.oxlintrc.json` з каноном пакета `@nitra/cursor` (включає всі правила з канону та інші поля з `oxlint-canonical.json`). Дозволено додати лише ключі в `rules`; інші поля мають збігатися з каноном.
|
|
43
|
+
check — Перевіряє відповідність проєкту правилам js-lint.mdc
|
|
340
44
|
|
|
341
|
-
|
|
45
|
+
## Гарантії поведінки
|
|
342
46
|
|
|
343
|
-
-
|
|
344
|
-
-
|
|
345
|
-
-
|
|
346
|
-
-
|
|
347
|
-
-
|
|
348
|
-
- експорт `check(cwd = process.cwd())`, який створює репортер через `createCheckReporter`, послідовно `await`-ить п’ять чекерів у порядку _ESLint → package.json → oxlint → workflows → knip_, потім перевіряє legacy-конфіги ESLint і повертає `reporter.getExitCode()`.
|
|
47
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
48
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
49
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
50
|
+
- Свідомо пропускає шляхи: `.github`, `.git`.
|
|
51
|
+
- Не звертається до мережі.
|
|
@@ -1,163 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/rules/js-lint-ci/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
|
+
Файл застосовує визначене правило до вхідного контексту прогону. Застосовує правило та повертає отриманий результат.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
2. **Standalone mode** — якщо файл запущено напряму через `bun rules/js-lint-ci/fix.mjs`, виконується повний еквівалент CLI-команди `npx @nitra/cursor fix js-lint-ci` (з завантаженням конфігу, whitelist, summary та exit-кодом для CI).
|
|
14
|
+
## Поведінка
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
1. Запуск правила.
|
|
17
|
+
* Приймає контекст прогону.
|
|
18
|
+
* Виконує правило.
|
|
19
|
+
* Повертає результат.
|
|
17
20
|
|
|
18
|
-
|
|
19
|
-
applies → JS-concerns → policy → mdc-refs
|
|
20
|
-
```
|
|
21
|
+
## Публічний API
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
24
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
23
25
|
|
|
24
|
-
##
|
|
26
|
+
## Гарантії поведінки
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
Інших іменованих чи default-експортів файл не містить.
|
|
31
|
-
|
|
32
|
-
### Сигнатура `run`
|
|
33
|
-
|
|
34
|
-
```js
|
|
35
|
-
export function run(ctx)
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
#### Параметри
|
|
39
|
-
|
|
40
|
-
- `ctx` (необов’язковий) — об’єкт контексту прогону типу `RuleContext` (визначення в модулі `../../scripts/lib/run-standard-rule.mjs`). Через цей контекст передаються спільні для одного запуску артефакти, такі як кеш обходу файлової системи (`walkCache`) тощо. Якщо контекст відсутній, `runStandardRule` створює власний.
|
|
41
|
-
|
|
42
|
-
#### Повертає
|
|
43
|
-
|
|
44
|
-
- `Promise<number>` — асинхронно резолвиться у **exit-код**:
|
|
45
|
-
- `0` — порушень немає, правило пройшло успішно;
|
|
46
|
-
- `1` — виявлено порушення (правило завершилось зі статусом FAIL).
|
|
47
|
-
|
|
48
|
-
#### Side effects
|
|
49
|
-
|
|
50
|
-
Сам по собі `run` не має прямих побічних ефектів, але через делегування у `runStandardRule` ініціює:
|
|
51
|
-
|
|
52
|
-
- читання конфігураційних файлів правила (зокрема `meta.json`, файлів `applies/*`, `policy/*`, `mdc-refs/*` тощо — згідно конвенції стандартного правила);
|
|
53
|
-
- обхід файлів проєкту відповідно до `applies`-патернів;
|
|
54
|
-
- виконання JS-перевірок (наприклад, запуск ESLint у відповідному режимі) та політики;
|
|
55
|
-
- запис до stdout/stderr діагностики, summary та результатів;
|
|
56
|
-
- може кешувати/читати з `walkCache` всередині `ctx`.
|
|
57
|
-
|
|
58
|
-
## Функції
|
|
59
|
-
|
|
60
|
-
### `run(ctx)`
|
|
61
|
-
|
|
62
|
-
```js
|
|
63
|
-
/**
|
|
64
|
-
*
|
|
65
|
-
*/
|
|
66
|
-
export function run(ctx) {
|
|
67
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
- **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`.
|
|
72
|
-
- **Параметри:**
|
|
73
|
-
- `ctx` — опційний контекст прогону (див. вище).
|
|
74
|
-
- **Повертає:** `Promise<number>` — exit-код прогону правила (0/1).
|
|
75
|
-
- **Реалізація:** єдиний виклик `runStandardRule(import.meta.dirname, ctx)`. Перший аргумент `import.meta.dirname` — абсолютний шлях до каталогу, у якому розташований цей файл (`.../npm/rules/js-lint-ci/`). Таким чином `runStandardRule` дізнається, **яке саме правило** виконувати: всі його артефакти (`meta.json`, `applies`, `policy`, `mdc-refs` тощо) лежать поряд з `fix.mjs`.
|
|
76
|
-
- **Side effects:** делеговані у `runStandardRule` (див. секцію _Експорти / API_ вище).
|
|
77
|
-
|
|
78
|
-
### Standalone-блок (top-level `if`)
|
|
79
|
-
|
|
80
|
-
```js
|
|
81
|
-
if (isRunAsCli(import.meta.url)) {
|
|
82
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
- Це не функція, а **умовний top-level statement**, що виконується лише коли модуль завантажено як головний (а не як імпортований модуль).
|
|
87
|
-
- **Умова:** `isRunAsCli(import.meta.url)` — повертає `true`, якщо поточний модуль є точкою входу процесу (тобто запущено `bun rules/js-lint-ci/fix.mjs`, а не `import` з іншого файлу).
|
|
88
|
-
- **Дія:** виконує `await runRuleCli(import.meta.dirname)` — повний CLI-сценарій (config-loading, whitelist, summary), а потім завершує процес `process.exit(<exit-code>)` з тим самим кодом, що повернув `runRuleCli` (0 або 1) — це критично для CI/IDE, які орієнтуються на код виходу.
|
|
89
|
-
- **Side effects:** завершення процесу (`process.exit`), вся I/O `runRuleCli`. Виклики `process.exit` тут спеціально дозволені директивою:
|
|
90
|
-
```js
|
|
91
|
-
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Залежності
|
|
95
|
-
|
|
96
|
-
### Внутрішні (модулі того ж пакета)
|
|
97
|
-
|
|
98
|
-
- `../../scripts/lib/run-rule-cli.mjs` — імпортуються:
|
|
99
|
-
- `isRunAsCli(metaUrl)` — детектор того, що поточний ESM-модуль запущено як CLI-entry;
|
|
100
|
-
- `runRuleCli(dirname)` — full standalone CLI-runner правила, що дзеркалить поведінку `npx @nitra/cursor fix <id>` (config-loading + whitelist + summary).
|
|
101
|
-
- `../../scripts/lib/run-standard-rule.mjs` — імпортується:
|
|
102
|
-
- `runStandardRule(dirname, ctx?)` — стандартний бібліотечний конвеєр правила (`applies → JS-concerns → policy → mdc-refs`).
|
|
103
|
-
|
|
104
|
-
### Зовнішні (поза репозиторієм)
|
|
105
|
-
|
|
106
|
-
- Стандартні Node/Bun-глобали: `process` (для `process.exit`), `import.meta.dirname`, `import.meta.url`.
|
|
107
|
-
- Прямих залежностей від npm-пакетів у самому файлі немає (вони — транзитивні через `run-rule-cli.mjs` / `run-standard-rule.mjs`).
|
|
108
|
-
|
|
109
|
-
### Типи (через JSDoc)
|
|
110
|
-
|
|
111
|
-
- `import('../../scripts/lib/run-standard-rule.mjs').RuleContext` — імпорт типу для параметра `ctx`.
|
|
112
|
-
|
|
113
|
-
## Потік виконання / Використання
|
|
114
|
-
|
|
115
|
-
### Сценарій 1. Library mode (виклик з оркестратора)
|
|
116
|
-
|
|
117
|
-
Виконується, коли інший модуль імпортує цей файл та викликає `run(ctx)`:
|
|
118
|
-
|
|
119
|
-
```js
|
|
120
|
-
import { run } from '@nitra/cursor/rules/js-lint-ci/fix.mjs'
|
|
121
|
-
|
|
122
|
-
const exitCode = await run(ctx)
|
|
123
|
-
if (exitCode !== 0) {
|
|
124
|
-
// правило виявило порушення
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
Послідовність:
|
|
129
|
-
|
|
130
|
-
1. Оркестратор передає (опційно) спільний `ctx` (наприклад, з `walkCache`).
|
|
131
|
-
2. `run` викликає `runStandardRule(import.meta.dirname, ctx)`.
|
|
132
|
-
3. `runStandardRule` зчитує конфіг правила з каталогу `npm/rules/js-lint-ci/` і послідовно проганяє ланцюжок:
|
|
133
|
-
- `applies` — визначає список файлів, до яких застосовне правило;
|
|
134
|
-
- `JS-concerns` — JS-специфічні перевірки;
|
|
135
|
-
- `policy` — політика правила;
|
|
136
|
-
- `mdc-refs` — звірення з посиланнями `.mdc`.
|
|
137
|
-
4. Повертається `Promise<number>` з exit-кодом.
|
|
138
|
-
|
|
139
|
-
У цьому сценарії `process.exit` **не** викликається — exit-код повертається у викликача, який сам вирішує, що з ним робити (наприклад, агрегує з кодами інших правил).
|
|
140
|
-
|
|
141
|
-
### Сценарій 2. Standalone mode (прямий запуск)
|
|
142
|
-
|
|
143
|
-
Виконується командою:
|
|
144
|
-
|
|
145
|
-
```sh
|
|
146
|
-
bun npm/rules/js-lint-ci/fix.mjs
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Послідовність:
|
|
150
|
-
|
|
151
|
-
1. ESM-модуль завантажується як головний, `import.meta.url` дорівнює URL процесу.
|
|
152
|
-
2. Виконується top-level `if (isRunAsCli(import.meta.url))` — умова істинна.
|
|
153
|
-
3. Запускається `await runRuleCli(import.meta.dirname)` — повний CLI-сценарій (config, whitelist, summary), еквівалентний `npx @nitra/cursor fix js-lint-ci`.
|
|
154
|
-
4. `process.exit(<code>)` завершує процес з отриманим exit-кодом (0/1) — для коректної інтеграції з CI та IDE.
|
|
155
|
-
|
|
156
|
-
> Експортована функція `run` у цьому сценарії **не** викликається напряму — `runRuleCli` сам інкапсулює всю CLI-логіку, включно з потрібними викликами `runStandardRule` всередині.
|
|
157
|
-
|
|
158
|
-
### Чому існують обидві ролі
|
|
159
|
-
|
|
160
|
-
- **Library `run`** потрібна, щоб агрегатор (`npx @nitra/cursor fix` без id або фоновий runner) міг прогнати багато правил у спільному контексті — з кешуванням обходу ФС, єдиним підсумком тощо, без породження окремого процесу на кожне правило.
|
|
161
|
-
- **Standalone-блок** потрібен, щоб правило було самодостатнім: розробник може запустити його в IDE «як файл» і отримати повноцінний CLI-сценарій з коректним exit-кодом. Це особливо зручно для дебагу окремого правила без переходу через головний CLI пакета.
|
|
162
|
-
|
|
163
|
-
Файл свідомо тримається **мінімальним**: він є лише адаптером (entry-point), уся доменна логіка — у бібліотечних функціях `runStandardRule` та `runRuleCli`. Це уніфікує всі правила з каталогу `npm/rules/*` — їхні `fix.mjs` мають однакову структуру і відрізняються лише шляхом каталогу, у якому лежать (через `import.meta.dirname`).
|
|
28
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
29
|
+
- Кешує результати в межах одного прогону.
|
|
30
|
+
- Не звертається до мережі.
|