@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,141 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
docgen:
|
|
3
3
|
source: npm/rules/image-avif/fix.mjs
|
|
4
|
-
crc:
|
|
4
|
+
crc: 38cf876b
|
|
5
|
+
score: 100
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
#
|
|
8
|
+
# fix.mjs
|
|
8
9
|
|
|
9
10
|
## Огляд
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
Обробляє JS-занепокоєні до політики для MDC-референсів на основі наданого контексту прогону та повертає результат
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
- `meta.json` — метадані (наприклад, `auto`-залежності, тут `{"auto": ["vue", "image-compress"]}`);
|
|
15
|
-
- `<id>.mdc` — людино-зрозумілий опис правила для Cursor;
|
|
16
|
-
- підтек `js/` (concerns на рівні JS-AST/тексту) і `policy/` (rego-policy).
|
|
14
|
+
## Поведінка
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
1. Запуск правила.
|
|
17
|
+
* Приймає контекст прогону.
|
|
18
|
+
* Виконує застосування JS-занепокоєних до політики до MDC-референсів.
|
|
19
|
+
* Повертає результат.
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
2. **Standalone-режим.** Якщо файл запущено напряму (`bun npm/rules/image-avif/fix.mjs` або еквівалент), він самостійно піднімає повний CLI-цикл (`runRuleCli`) — з підвантаженням конфігурації, whitelist та виведенням підсумку — і завершує процес кодом 0/1.
|
|
21
|
+
## Публічний API
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
24
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
24
25
|
|
|
25
|
-
##
|
|
26
|
+
## Гарантії поведінки
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Інших іменованих чи default-експортів файл не має.
|
|
32
|
-
|
|
33
|
-
Окрім експорту, у файлі є **top-level side-effect**: блок `if (isRunAsCli(import.meta.url)) { … process.exit(await runRuleCli(...)) }`. Він спрацьовує **лише** коли цей `.mjs` запущено як CLI-entry (а не імпортовано як модуль), і завершує процес кодом, який повернув `runRuleCli`.
|
|
34
|
-
|
|
35
|
-
## Функції
|
|
36
|
-
|
|
37
|
-
### `run(ctx)`
|
|
38
|
-
|
|
39
|
-
```js
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
*/
|
|
43
|
-
export function run(ctx) {
|
|
44
|
-
return runStandardRule(import.meta.dirname, ctx)
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
- **Сигнатура:** `run(ctx?: RuleContext): Promise<number>`.
|
|
49
|
-
- **Параметри:**
|
|
50
|
-
- `ctx` — необов'язковий контекст прогону (`RuleContext`), імпортується з `../../scripts/lib/run-standard-rule.mjs`. У документації самого файла зазначено, що в `ctx` передається, наприклад, `walkCache` — спільний кеш обходу файлової системи, щоб не повторювати walk між правилами в межах одного CLI-прогону. Якщо `ctx` не передано, `runStandardRule` сам ініціалізує необхідне.
|
|
51
|
-
- **Повертає:** `Promise<number>` — числовий exit-код:
|
|
52
|
-
- `0` — правило виконано без порушень;
|
|
53
|
-
- `1` — знайдені порушення (несумісність із `image-avif`).
|
|
54
|
-
- **Що робить усередині:** єдиним викликом делегує всю роботу в `runStandardRule(dir, ctx)`. Перший аргумент — `import.meta.dirname`, тобто **абсолютний шлях до теки `npm/rules/image-avif/`** на диску. Саме цей шлях `runStandardRule` використовує, щоб знайти сусідні `meta.json`, теку `js/` (JS-concerns) та теку `policy/` (rego-policy) і прогнати їх по конвеєру.
|
|
55
|
-
- **Side effects:** прямих side-effects сама функція не виконує. Усі ефекти (читання файлів, виклик `opa`, форматування звіту) інкапсульовано в `runStandardRule`. Функція асинхронна (повертає `Promise`), бо `runStandardRule` повертає `Promise`.
|
|
56
|
-
|
|
57
|
-
### Top-level CLI-блок (не функція, але важливий side-effect)
|
|
58
|
-
|
|
59
|
-
```js
|
|
60
|
-
if (isRunAsCli(import.meta.url)) {
|
|
61
|
-
// eslint-disable-next-line n/no-process-exit
|
|
62
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
- **Умова входу:** `isRunAsCli(import.meta.url)` повертає `true`, лише якщо файл стартовано напряму як скрипт (Node.js/Bun), а не імпортовано як модуль. Це класичний `__main__`-патерн для ESM.
|
|
67
|
-
- **Що робить:** викликає `runRuleCli(import.meta.dirname)` — повноцінний CLI-обгортувач, який, на відміну від `runStandardRule`, додатково підтягує конфігурацію проєкту, застосовує whitelist і друкує summary (як коментар у файлі: «повний еквівалент `npx @nitra/cursor fix <id>`»). Результатом є `Promise<number>` із exit-кодом.
|
|
68
|
-
- **Завершення:** `process.exit(...)` примусово завершує процес із отриманим exit-кодом. Це навмисно — для CI/IDE інтеграцій, які зчитують exit-код. Через це поряд стоять директиви `eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit` із поясненням («standalone entry-point має повертати exit-code для CI/IDE»).
|
|
69
|
-
- **`await` на top-level:** доступний завдяки тому, що файл є ESM-модулем (`.mjs`) і виконується в середовищі з підтримкою top-level await (Node.js ≥ 14.8 / Bun).
|
|
70
|
-
|
|
71
|
-
## Залежності
|
|
72
|
-
|
|
73
|
-
### Імпорти з сусідніх модулів пакета
|
|
74
|
-
|
|
75
|
-
| Імпорт | Звідки | Призначення |
|
|
76
|
-
| ----------------- | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
77
|
-
| `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Предикат: чи поточний модуль виконано напряму як CLI (порівнює `import.meta.url` зі скриптом, який стартував процес). |
|
|
78
|
-
| `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Standalone CLI-обгортка: завантажує конфігурацію, формує whitelist, прогоняє правило (через той самий `runStandardRule` усередині) і повертає exit-код. |
|
|
79
|
-
| `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Стандартний пайплайн правила: послідовно виконує фази **applies → JS-concerns → policy → mdc-refs**, базуючись на структурі теки правила (передано через `dirname`). |
|
|
80
|
-
|
|
81
|
-
Шляхи відносні: `../../scripts/lib/...` означає `npm/scripts/lib/...` (з огляду на розташування файла в `npm/rules/image-avif/`).
|
|
82
|
-
|
|
83
|
-
### JSDoc-залежності типів
|
|
84
|
-
|
|
85
|
-
У JSDoc вказано тип `import('../../scripts/lib/run-standard-rule.mjs').RuleContext` для параметра `ctx`. Це **type-only** імпорт: на runtime він не існує, лише підказує IDE/типчекеру форму об'єкта контексту.
|
|
86
|
-
|
|
87
|
-
### Сусідні артефакти правила (не імпортуються тут, але необхідні `runStandardRule`)
|
|
88
|
-
|
|
89
|
-
- `npm/rules/image-avif/meta.json` — `{ "auto": ["vue", "image-compress"] }`. Поле `auto` декларує, які інші правила автоматично «тягнуться» разом із `image-avif`.
|
|
90
|
-
- `npm/rules/image-avif/js/` — каталог JS-concerns (тек з функціями перевірки/трансформації).
|
|
91
|
-
- `npm/rules/image-avif/policy/` — каталог rego-policy для фази `policy`.
|
|
92
|
-
- `npm/rules/image-avif/image-avif.mdc` — людинозрозумілий опис правила (для Cursor) — використовується у фазі `mdc-refs`.
|
|
93
|
-
|
|
94
|
-
### Зовнішні залежності
|
|
95
|
-
|
|
96
|
-
Прямих імпортів зовнішніх npm-пакетів у файлі немає. Усі залежності — внутрішні до пакета `@nitra/cursor`.
|
|
97
|
-
|
|
98
|
-
## Потік виконання / Використання
|
|
99
|
-
|
|
100
|
-
### Сценарій 1. Library-режим (через CLI-orchestrator)
|
|
101
|
-
|
|
102
|
-
Коли користувач запускає `npx @nitra/cursor fix` (або відповідну скіл-команду на кшталт `/n-fix`), верхньорівневий orchestrator:
|
|
103
|
-
|
|
104
|
-
1. Обходить теку `npm/rules/`, знаходить правило `image-avif`.
|
|
105
|
-
2. Динамічно імпортує `npm/rules/image-avif/fix.mjs` як ESM-модуль. У цей момент top-level `if (isRunAsCli(...))` повертає `false` (файл не запущено напряму), тож `process.exit` **не** викликається.
|
|
106
|
-
3. Викликає `run(ctx)`, передаючи спільний контекст (наприклад, із заздалегідь побудованим `walkCache`).
|
|
107
|
-
4. Усередині `run` делегує в `runStandardRule(import.meta.dirname, ctx)`, який послідовно проходить чотири фази:
|
|
108
|
-
- **applies** — визначає, до яких файлів проєкту правило взагалі застосовне;
|
|
109
|
-
- **JS-concerns** — запускає функції з теки `js/` для AST/текстових перевірок;
|
|
110
|
-
- **policy** — викликає `opa` з rego-файлами з `policy/`;
|
|
111
|
-
- **mdc-refs** — звіряє посилання у `.mdc`.
|
|
112
|
-
5. Отримує `0`/`1`, передає назад orchestratorу, який агрегує результати всіх правил у спільний summary.
|
|
113
|
-
|
|
114
|
-
### Сценарій 2. Standalone-режим (для дебагу/CI)
|
|
115
|
-
|
|
116
|
-
Користувач (або IDE/CI) запускає файл напряму:
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
bun npm/rules/image-avif/fix.mjs
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
1. Бунт/Node стартує файл як ESM-скрипт. Виконуються імпорти.
|
|
123
|
-
2. Експорт `run` зареєстровано, але **не викликається** — поза CLI-orchestratorом нікому його смикати.
|
|
124
|
-
3. Виконується top-level `if`: `isRunAsCli(import.meta.url)` повертає `true`.
|
|
125
|
-
4. Викликається `await runRuleCli(import.meta.dirname)` — повний еквівалент `npx @nitra/cursor fix image-avif`: завантаження конфігурації проєкту, whitelist, прогін правила (через той самий `runStandardRule` усередині `runRuleCli`), друк summary.
|
|
126
|
-
5. `process.exit(<exitCode>)` завершує процес із кодом, який бачить CI/IDE.
|
|
127
|
-
|
|
128
|
-
### Дизайн-патерн: dual-role entry-point
|
|
129
|
-
|
|
130
|
-
У коментарі автор файла прямо називає цей патерн: «Дві ролі fix.mjs: library (run) + standalone (main)». Це повторюваний патерн для всіх правил пакета — кожне правило має свій `fix.mjs` із такою ж двоїстою структурою. Завдяки цьому:
|
|
131
|
-
|
|
132
|
-
- CLI-orchestrator може **переюзати** ту саму функцію `run`, не дублюючи виклик `process.exit`;
|
|
133
|
-
- розробник може **локально дебажити** одне правило, запустивши його `fix.mjs` напряму;
|
|
134
|
-
- логіка пайплайну живе в одному місці (`runStandardRule`), а entry-point залишається тонким.
|
|
135
|
-
|
|
136
|
-
### Що цей файл **не** робить
|
|
137
|
-
|
|
138
|
-
- Не визначає, **які саме** файли проєкту порушують `image-avif` — це робить тека `js/` і `policy/`.
|
|
139
|
-
- Не парсить аргументи CLI — це робить `runRuleCli`.
|
|
140
|
-
- Не пише в stdout/stderr напряму — увесь вивід формує `runStandardRule`/`runRuleCli`.
|
|
141
|
-
- Не модифікує файли проєкту — назва `fix` тут історична (контракт стандартного правила); фактична семантика — це check + (потенційно) auto-fix усередині concerns, але сам `fix.mjs` лише оркеструє.
|
|
28
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
29
|
+
- Кешує результати в межах одного прогону.
|
|
30
|
+
- Не звертається до мережі.
|
|
@@ -1,150 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/image-compress/fix.mjs
|
|
4
|
+
crc: 38cf876b
|
|
5
|
+
score: 100
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Файл `npm/rules/image-compress/fix.mjs` — це уніфікована точка входу (entry-point) для правила `image-compress` із набору правил `@nitra/cursor`. Він виконує дві ролі одночасно:
|
|
6
|
-
|
|
7
|
-
1. **Library mode** — експортує функцію `run(ctx)`, яку викликає CLI-оркестратор `@nitra/cursor` (через динамічний `import` модуля та виклик `run(ctx)`) разом з іншими правилами в межах одного загального прогону (з конфіг-завантаженням, whitelist та підсумковим звітом).
|
|
8
|
-
2. **Standalone mode** — якщо файл запущено напряму через `bun rules/image-compress/fix.mjs` (тобто є точкою входу процесу), він самостійно піднімає повний CLI-оркестратор для цього єдиного правила і завершує процес кодом виходу, придатним для CI/IDE.
|
|
9
|
-
|
|
10
|
-
Уся логіка правила (виявлення `applies`, перевірка JS-concerns, policy, валідація mdc-refs) делегується у `runStandardRule` зі спільної бібліотеки `scripts/lib/run-standard-rule.mjs`. Тобто сам `fix.mjs` правила `image-compress` не містить власної бізнес-логіки — він лише прив’язує спільний “стандартний” пайплайн правил до конкретної директорії цього правила через `import.meta.dirname`.
|
|
11
|
-
|
|
12
|
-
Правило `image-compress` належить до родини стандартних правил `@nitra/cursor`, де кожне правило живе у власній теці `npm/rules/<id>/` і має однаковий каркас: `fix.mjs` (цей файл), `check-*.mjs` (детектори порушень), `*.mdc` (людинозрозумілий опис правила) та інші артефакти, які `runStandardRule` автоматично знаходить за домовленостями про шляхи.
|
|
13
|
-
|
|
14
|
-
## Експорти / API
|
|
15
|
-
|
|
16
|
-
Модуль має один іменований експорт.
|
|
17
|
-
|
|
18
|
-
### `run(ctx?) → Promise<number>`
|
|
19
|
-
|
|
20
|
-
Function, що повертає `Promise<number>` — exit-code прогону правила:
|
|
21
|
-
|
|
22
|
-
- `0` — правило відпрацювало без порушень (OK).
|
|
23
|
-
- `1` — знайдено порушення політики/перевірок правила.
|
|
24
|
-
|
|
25
|
-
Параметри:
|
|
26
|
-
|
|
27
|
-
- `ctx` (необов’язковий) — об’єкт `RuleContext` з `scripts/lib/run-standard-rule.mjs`. Використовується для спільного стану між правилами в межах одного прогону, зокрема для кешу обходу файлової системи (`walkCache`) та інших оркестраційних метаданих. Якщо не передано — `runStandardRule` сам ініціалізує внутрішній контекст.
|
|
28
|
-
|
|
29
|
-
Призначення: викликається CLI-оркестратором `@nitra/cursor` як library API. Зовнішній код виконує `import { run } from '<абсолютний шлях>/npm/rules/image-compress/fix.mjs'` і потім `await run(ctx)`. Це дозволяє запускати багато правил в одному процесі з єдиним конфіг-завантаженням і єдиним звітом.
|
|
30
|
-
|
|
31
|
-
Модуль не має `export default`, не експортує жодних інших символів, констант чи типів.
|
|
32
|
-
|
|
33
|
-
## Функції
|
|
34
|
-
|
|
35
|
-
### `run(ctx)`
|
|
36
|
-
|
|
37
|
-
**Сигнатура:**
|
|
38
|
-
|
|
39
|
-
```js
|
|
40
|
-
export function run(ctx)
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
**JSDoc-тип (як у вихідному файлі):**
|
|
44
|
-
|
|
45
|
-
- `@param {import('../../scripts/lib/run-standard-rule.mjs').RuleContext} [ctx]` — контекст прогону (наприклад, `walkCache`); параметр опціональний.
|
|
46
|
-
- `@returns {Promise<number>}` — `0` означає OK, `1` — порушення.
|
|
47
|
-
|
|
48
|
-
**Параметри:**
|
|
49
|
-
|
|
50
|
-
- `ctx?: RuleContext` — необов’язковий контекст із зовнішнього оркестратора; пробрасується далі без модифікації.
|
|
51
|
-
|
|
52
|
-
**Що робить:**
|
|
53
|
-
|
|
54
|
-
1. Звертається до `import.meta.dirname` — це абсолютний шлях до директорії, у якій лежить сам `fix.mjs` (тобто до `npm/rules/image-compress/`).
|
|
55
|
-
2. Викликає `runStandardRule(import.meta.dirname, ctx)` — стандартну реалізацію пайплайну правила: applies → JS-concerns → policy → mdc-refs.
|
|
56
|
-
3. Повертає `Promise<number>`, який вирішить exit-code від `runStandardRule`.
|
|
57
|
-
|
|
58
|
-
**Повертає:** `Promise<number>` — exit-code пайплайна (`0` або `1`).
|
|
8
|
+
# fix.mjs
|
|
59
9
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
### Standalone-блок (не функція, а top-level код)
|
|
63
|
-
|
|
64
|
-
**Сигнатура:**
|
|
65
|
-
|
|
66
|
-
```js
|
|
67
|
-
if (isRunAsCli(import.meta.url)) {
|
|
68
|
-
process.exit(await runRuleCli(import.meta.dirname))
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
**Що робить:**
|
|
73
|
-
|
|
74
|
-
1. `isRunAsCli(import.meta.url)` повертає `true`, якщо поточний модуль завантажено як точку входу процесу (а не як імпортовану бібліотеку). Це стандартний для Node/Bun спосіб розпізнати, що файл стартував напряму.
|
|
75
|
-
2. Якщо так — викликає `runRuleCli(import.meta.dirname)`, який реалізує повний CLI-оркестратор саме для цього правила: завантаження конфігу, обчислення whitelist, виконання правила, друк підсумків. Він повертає `Promise<number>` — exit-code.
|
|
76
|
-
3. `await` чекає виконання promise. Це — top-level `await`, що дозволено в ES-модулях.
|
|
77
|
-
4. `process.exit(<code>)` передає отриманий exit-code операційній системі / CI / IDE. ESLint-правила `n/no-process-exit` і `unicorn/no-process-exit` тут свідомо вимкнено коментарем, оскільки standalone entry-point правомірно завершує процес явним кодом.
|
|
78
|
-
|
|
79
|
-
**Параметри / повертає:** немає (це side-effect блок верхнього рівня модуля).
|
|
80
|
-
|
|
81
|
-
**Side effects:**
|
|
82
|
-
|
|
83
|
-
- Якщо файл імпортовано як бібліотеку — гілка не виконується, бо `isRunAsCli` поверне `false`.
|
|
84
|
-
- Якщо файл запущено напряму — повний CLI-оркестратор виконує власні I/O (читання конфігу, обхід проєкту, друк звіту) і потім завершує процес через `process.exit`.
|
|
85
|
-
|
|
86
|
-
## Залежності
|
|
87
|
-
|
|
88
|
-
### Внутрішні модулі проєкту
|
|
89
|
-
|
|
90
|
-
- `../../scripts/lib/run-rule-cli.mjs` — постачає:
|
|
91
|
-
- `isRunAsCli(metaUrl)` — детектор, чи модуль є entry-point процесу (за `import.meta.url`).
|
|
92
|
-
- `runRuleCli(ruleDirname)` — standalone CLI-оркестратор для одного правила: конфіг + whitelist + summary + exit-code. Аналогічний за поведінкою до `npx @nitra/cursor fix <id>`.
|
|
93
|
-
- `../../scripts/lib/run-standard-rule.mjs` — постачає:
|
|
94
|
-
- `runStandardRule(ruleDirname, ctx?)` — стандартний пайплайн правила: applies → JS-concerns → policy → mdc-refs.
|
|
95
|
-
- Тип `RuleContext` (через JSDoc-`import('...')`), який описує спільний контекст прогону (зокрема `walkCache`).
|
|
96
|
-
|
|
97
|
-
Шляхи відносні: `../../scripts/lib/...` з директорії `npm/rules/image-compress/` веде до `npm/scripts/lib/...`.
|
|
98
|
-
|
|
99
|
-
### Платформенні API
|
|
100
|
-
|
|
101
|
-
- `import.meta.dirname` — стандартна властивість ES-модулів у сучасних рантаймах (Node.js та Bun), містить абсолютну директорію поточного модуля.
|
|
102
|
-
- `import.meta.url` — стандартна властивість ES-модулів; URL-форма шляху поточного модуля; використовується для розпізнавання запуску як CLI.
|
|
103
|
-
- `process.exit(code)` — глобальний Node/Bun API завершення процесу з кодом виходу.
|
|
104
|
-
- Top-level `await` — підтримується в ESM.
|
|
105
|
-
|
|
106
|
-
### Зовнішні npm-пакети
|
|
107
|
-
|
|
108
|
-
Прямих імпортів зовнішніх npm-пакетів у файлі немає. Уся залежність на зовнішнє API проходить транзитивно через `run-rule-cli.mjs` та `run-standard-rule.mjs`.
|
|
109
|
-
|
|
110
|
-
### ESLint-директиви
|
|
111
|
-
|
|
112
|
-
У файлі присутній один inline-disable: `n/no-process-exit, unicorn/no-process-exit` навколо `process.exit(...)`. Він локалізований лише до одного рядка і обґрунтований у коментарі: standalone entry-point має повертати exit-code для CI/IDE.
|
|
113
|
-
|
|
114
|
-
## Потік виконання / Використання
|
|
115
|
-
|
|
116
|
-
### Сценарій A: library-режим (через CLI `@nitra/cursor`)
|
|
117
|
-
|
|
118
|
-
1. CLI `@nitra/cursor` (наприклад, `npx @nitra/cursor fix` без аргументу-id) збирає список правил, серед яких є `image-compress`.
|
|
119
|
-
2. Оркестратор робить `import` модуля `npm/rules/image-compress/fix.mjs` і отримує іменований експорт `run`.
|
|
120
|
-
3. Викликає `await run(ctx)`, передаючи спільний `RuleContext` (з `walkCache` тощо).
|
|
121
|
-
4. `run` делегує виконання в `runStandardRule(import.meta.dirname, ctx)`, який виконує стандартний пайплайн правила (applies → JS-concerns → policy → mdc-refs) для теки `npm/rules/image-compress/`.
|
|
122
|
-
5. `run` повертає `Promise<number>`; оркестратор агрегує exit-коди всіх правил у загальний підсумок.
|
|
123
|
-
|
|
124
|
-
У цьому сценарії гілка `if (isRunAsCli(...))` НЕ виконується — `process.exit` не викликається, оскільки модуль завантажено як бібліотеку, а не як entry-point процесу.
|
|
125
|
-
|
|
126
|
-
### Сценарій B: standalone-режим (`bun rules/image-compress/fix.mjs`)
|
|
127
|
-
|
|
128
|
-
1. Користувач/CI запускає файл напряму: `bun rules/image-compress/fix.mjs` (або еквівалентна команда рантайму).
|
|
129
|
-
2. Виконується top-level код модуля, у тому числі гілка `if (isRunAsCli(import.meta.url))`.
|
|
130
|
-
3. Оскільки модуль — entry-point процесу, `isRunAsCli` повертає `true`.
|
|
131
|
-
4. Викликається `await runRuleCli(import.meta.dirname)`, який повністю відтворює оркестрацію `@nitra/cursor fix <id>` для саме цього правила: завантажує конфіг, обчислює whitelist, прогонить правило, друкує summary, повертає exit-code.
|
|
132
|
-
5. `process.exit(<code>)` завершує процес із цим кодом — придатним для CI-пайплайнів та IDE-інтеграцій.
|
|
10
|
+
## Огляд
|
|
133
11
|
|
|
134
|
-
|
|
12
|
+
Файл виконує запуск правила. Він приймає контекст прогону і повертає отриманий результат.
|
|
135
13
|
|
|
136
|
-
|
|
14
|
+
## Поведінка
|
|
137
15
|
|
|
138
|
-
|
|
139
|
-
|
|
16
|
+
1. Запуск правила.
|
|
17
|
+
* Приймає контекст прогону.
|
|
18
|
+
* Повертає результат прогону.
|
|
140
19
|
|
|
141
|
-
|
|
20
|
+
## Публічний API
|
|
142
21
|
|
|
143
|
-
|
|
22
|
+
run — запускає правило: applies → JS-concerns → policy → mdc-refs (через runStandardRule).
|
|
23
|
+
Library mode — викликається CLI orchestration через `import + run`.
|
|
144
24
|
|
|
145
|
-
|
|
146
|
-
- Standalone-гілка: `if (isRunAsCli(import.meta.url)) process.exit(await runRuleCli(import.meta.dirname))` — з inline-disable для `n/no-process-exit, unicorn/no-process-exit`.
|
|
147
|
-
- Імпортує `isRunAsCli` та `runRuleCli` зі `../../scripts/lib/run-rule-cli.mjs`, і `runStandardRule` зі `../../scripts/lib/run-standard-rule.mjs`.
|
|
148
|
-
- Жодних інших експортів, констант чи побічних дій верхнього рівня.
|
|
25
|
+
## Гарантії поведінки
|
|
149
26
|
|
|
150
|
-
|
|
27
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
28
|
+
- Кешує результати в межах одного прогону.
|
|
29
|
+
- Не звертається до мережі.
|
|
@@ -1,191 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
docgen:
|
|
3
|
+
source: npm/rules/image-compress/js/package_setup.mjs
|
|
4
|
+
crc: 13f6d8f3
|
|
5
|
+
score: 95
|
|
6
|
+
---
|
|
2
7
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Модуль `package_setup.mjs` реалізує `check`-функцію для правила `image-compress.mdc`. Правило вимагає, щоб у проєкті була налаштована оптимізація raster/SVG-зображень через CLI `@nitra/minify-image` ≥ 3.2.0 (запускається локально через `npx`).
|
|
6
|
-
|
|
7
|
-
У цьому файлі лишилися лише **FS / cross-file**-перевірки, які важко або незручно виразити декларативно у Rego:
|
|
8
|
-
|
|
9
|
-
- наявність `package.json` у корені репозиторію;
|
|
10
|
-
- `.n-minify-image.tsv` (committed source of truth split-cache 3.2.0 з полями sha1 / originalSize / size) **не** перебуває у `.gitignore` — файл має жити в git;
|
|
11
|
-
- застарілий `.minify-image-cache.tsv` (4-колонковий кеш з `@nitra/minify-image` < 3.2) видалений як з диска, так і з `.gitignore`.
|
|
12
|
-
|
|
13
|
-
Структурні вимоги до `package.json` (наявність `scripts.lint-image` з правильним викликом `npx @nitra/minify-image --src=. --write` без `--avif`, включення `bun run lint-image` в агрегований `lint`, відсутність `@nitra/minify-image` у `dependencies`/`devDependencies`) перевіряються Rego-політикою у `npm/rules/image-compress/policy/package_json/` і автофіксяться через `npx @nitra/cursor fix`.
|
|
14
|
-
|
|
15
|
-
CI-workflow для image-лінту правилом **не** вимагається — оптимізація відбувається лише локально перед комітом.
|
|
16
|
-
|
|
17
|
-
## Експорти / API
|
|
18
|
-
|
|
19
|
-
| Експорт | Тип | Призначення |
|
|
20
|
-
| ------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
21
|
-
| `check(cwd?)` | `async function` | Публічна точка входу. Виконує перевірки правила `image-compress.mdc` для вказаного робочого каталогу й повертає exit-код (`0` — OK, `1` — є помилки). |
|
|
22
|
-
|
|
23
|
-
Модуль використовує ES Modules (`.mjs`), іменований експорт `check`. Default-експорту немає.
|
|
24
|
-
|
|
25
|
-
## Функції
|
|
26
|
-
|
|
27
|
-
### `readGitignoreLines(cwd)`
|
|
28
|
-
|
|
29
|
-
Приватна допоміжна функція для читання змістовних рядків `.gitignore`.
|
|
30
|
-
|
|
31
|
-
- **Сигнатура:** `async function readGitignoreLines(cwd: string): Promise<string[] | null>`
|
|
32
|
-
- **Параметри:**
|
|
33
|
-
- `cwd` — абсолютний шлях до кореня репозиторію, де очікується `.gitignore`.
|
|
34
|
-
- **Повертає:**
|
|
35
|
-
- `null`, якщо файл `.gitignore` відсутній;
|
|
36
|
-
- масив рядків (`string[]`), кожен з яких уже `trim`-нутий, не порожній і не починається з `#`.
|
|
37
|
-
- **Side effects:** один синхронний `existsSync` і один асинхронний `readFile` (UTF-8) у файловій системі. Не пише нічого.
|
|
38
|
-
- **Поведінкові деталі:** коментарі визначаються лише за префіксом `#` на початку trim-нутого рядка; in-line коментарі (після `#` всередині рядка) не вирізаються.
|
|
39
|
-
|
|
40
|
-
### `checkHashCacheNotIgnored(pass, fail, cwd)`
|
|
41
|
-
|
|
42
|
-
Перевіряє, що файл `.n-minify-image.tsv` **не** перерахований у `.gitignore`. Файл є закомічуваним source of truth для split-cache 3.2.0 (зберігає sha1 + originalSize + size для slow-path і метрики lifetime savings), тому має потрапляти в git.
|
|
43
|
-
|
|
44
|
-
- **Сигнатура:** `async function checkHashCacheNotIgnored(pass: (msg: string) => void, fail: (msg: string) => void, cwd: string): Promise<void>`
|
|
45
|
-
- **Параметри:**
|
|
46
|
-
- `pass` — callback, що викликається при успіху з людиночитаним повідомленням;
|
|
47
|
-
- `fail` — callback, що викликається при провалі з повідомленням і вказівкою на дію;
|
|
48
|
-
- `cwd` — корінь репозиторію.
|
|
49
|
-
- **Повертає:** `Promise<void>`. Реєстрація результату здійснюється через `pass`/`fail` (зовнішній reporter).
|
|
50
|
-
- **Side effects:** одне читання `.gitignore` через `readGitignoreLines`.
|
|
51
|
-
- **Логіка:**
|
|
52
|
-
- якщо `.gitignore` є й містить точний рядок `.n-minify-image.tsv` → `fail` з вимогою прибрати рядок;
|
|
53
|
-
- інакше (файл відсутній або рядка немає) → `pass`.
|
|
54
|
-
- **Важливо:** сам факт існування `.n-minify-image.tsv` не вимагається. На новому проєкті без обробки зображень файла ще немає — і це нормально.
|
|
55
|
-
|
|
56
|
-
### `checkLegacyCacheRemoved(pass, fail, cwd)`
|
|
57
|
-
|
|
58
|
-
Перевіряє, що застарілий 4-колонковий кеш `.minify-image-cache.tsv` (з `@nitra/minify-image` < 3.2) повністю видалений з проєкту.
|
|
59
|
-
|
|
60
|
-
- **Сигнатура:** `async function checkLegacyCacheRemoved(pass: (msg: string) => void, fail: (msg: string) => void, cwd: string): Promise<void>`
|
|
61
|
-
- **Параметри:**
|
|
62
|
-
- `pass` — callback для успішного звіту;
|
|
63
|
-
- `fail` — callback для помилки;
|
|
64
|
-
- `cwd` — корінь репозиторію.
|
|
65
|
-
- **Повертає:** `Promise<void>`.
|
|
66
|
-
- **Side effects:** один `existsSync` на файл у корені; за умови, що файла нема, додатково читає `.gitignore`.
|
|
67
|
-
- **Логіка (виконується послідовно з `early return`):**
|
|
68
|
-
1. Якщо `<cwd>/.minify-image-cache.tsv` **існує на диску** → `fail` з готовим bash-snippet для повного видалення (`git rm --cached … && rm -f …`) і нагадуванням прибрати рядок з `.gitignore`. Подальші перевірки в цій функції пропускаються.
|
|
69
|
-
2. Інакше читає `.gitignore`; якщо там є точний рядок `.minify-image-cache.tsv` → `fail` з вимогою прибрати застарілий ігнор.
|
|
70
|
-
3. Інакше → `pass` («міграція на split-cache завершена»).
|
|
71
|
-
|
|
72
|
-
### `check(cwd?)`
|
|
8
|
+
# package_setup.mjs
|
|
73
9
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
- **Сигнатура:** `export async function check(cwd: string = process.cwd()): Promise<number>`
|
|
77
|
-
- **Параметри:**
|
|
78
|
-
- `cwd` — необов’язковий шлях до кореня репозиторію; за замовчуванням `process.cwd()`.
|
|
79
|
-
- **Повертає:** exit-код як `number` (`0` — все ок; `1` — є хоча б один `fail`). Значення формує `reporter.getExitCode()` з `createCheckReporter`.
|
|
80
|
-
- **Side effects:**
|
|
81
|
-
- друк звіту в stdout/stderr через reporter (формат залежить від `createCheckReporter`);
|
|
82
|
-
- читання файлів `package.json`, `.gitignore`, `.minify-image-cache.tsv` у `cwd`. Жодного запису на диск.
|
|
83
|
-
- **Поведінкові деталі:**
|
|
84
|
-
1. Створює локальний `reporter` через `createCheckReporter()` і дістає з нього `pass`/`fail`.
|
|
85
|
-
2. **Guard:** якщо в корені нема `package.json` — друкує `fail` із підказкою додати файл і **негайно повертає** `reporter.getExitCode()` (≈ `1`). Інші перевірки в цій ітерації не виконуються.
|
|
86
|
-
3. Якщо `package.json` є — `pass` з нагадуванням, що структуру `scripts` перевіряє Rego через `npx @nitra/cursor fix → image_compress.package_json`.
|
|
87
|
-
4. Виконує `checkHashCacheNotIgnored` (await).
|
|
88
|
-
5. Виконує `checkLegacyCacheRemoved` (await).
|
|
89
|
-
6. Повертає `reporter.getExitCode()`.
|
|
90
|
-
|
|
91
|
-
## Залежності
|
|
92
|
-
|
|
93
|
-
### Зовнішні (Node.js core)
|
|
94
|
-
|
|
95
|
-
- `node:fs`
|
|
96
|
-
- `existsSync` — синхронна перевірка існування `package.json`, `.gitignore`, застарілого кешу;
|
|
97
|
-
- `node:fs/promises`
|
|
98
|
-
- `readFile` — асинхронне читання `.gitignore` у кодуванні UTF-8;
|
|
99
|
-
- `node:path`
|
|
100
|
-
- `join` — кросплатформена побудова шляхів від кореня репозиторію.
|
|
101
|
-
|
|
102
|
-
### Внутрішні
|
|
103
|
-
|
|
104
|
-
- `../../../scripts/lib/check-reporter.mjs`
|
|
105
|
-
- `createCheckReporter()` — створює об’єкт із методами `pass(msg)`, `fail(msg)` і `getExitCode()`. Інкапсулює формат друку результатів і агрегацію статусу.
|
|
106
|
-
|
|
107
|
-
### Файли проєкту, з якими взаємодіє
|
|
108
|
-
|
|
109
|
-
- `<cwd>/package.json` — лише перевірка існування;
|
|
110
|
-
- `<cwd>/.gitignore` — читання й пошук рядків `.n-minify-image.tsv`, `.minify-image-cache.tsv`;
|
|
111
|
-
- `<cwd>/.minify-image-cache.tsv` — лише перевірка існування (legacy-файл, який має бути відсутній);
|
|
112
|
-
- `<cwd>/.n-minify-image.tsv` — **не** перевіряється напряму на диску, лише на присутність у `.gitignore`.
|
|
113
|
-
|
|
114
|
-
### Зовнішня політика
|
|
115
|
-
|
|
116
|
-
- `npm/rules/image-compress/policy/package_json/` — Rego-правила, які перевіряють і автофіксять структуру `package.json` (script `lint-image`, агрегований `lint`, відсутність залежності `@nitra/minify-image`).
|
|
117
|
-
|
|
118
|
-
## Потік виконання / Використання
|
|
119
|
-
|
|
120
|
-
### Як викликається
|
|
121
|
-
|
|
122
|
-
`check(cwd)` запускається оркестратором `@nitra/cursor` як одна з перевірок правила `image-compress.mdc`. У типовому сценарії команда `npx @nitra/cursor check` або `npx @nitra/cursor fix` обходить активні правила, для кожного імпортує його `check` і збирає звіт.
|
|
123
|
-
|
|
124
|
-
Можливий також прямий ESM-імпорт:
|
|
125
|
-
|
|
126
|
-
```js
|
|
127
|
-
import { check } from '@nitra/cursor/npm/rules/image-compress/js/package_setup.mjs'
|
|
128
|
-
|
|
129
|
-
const exitCode = await check(process.cwd())
|
|
130
|
-
process.exit(exitCode)
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
### Послідовність кроків усередині `check`
|
|
134
|
-
|
|
135
|
-
1. Створюється `reporter`, з нього дістаються `pass`/`fail`.
|
|
136
|
-
2. Перевірка наявності `package.json` (guard з early return при відсутності).
|
|
137
|
-
3. `await checkHashCacheNotIgnored(pass, fail, cwd)` — гарантує, що split-cache не виключений із git.
|
|
138
|
-
4. `await checkLegacyCacheRemoved(pass, fail, cwd)` — гарантує, що legacy-кеш не висить ні на диску, ні в `.gitignore`.
|
|
139
|
-
5. Повертається `reporter.getExitCode()`.
|
|
10
|
+
## Огляд
|
|
140
11
|
|
|
141
|
-
|
|
12
|
+
Файл виконує перевірку наявності та видалення кешу. Він зчитує рядки з `.gitignore`, перевіряє наявність кешу `HASH_CACHE_FILENAME` та видаляє застарілий кеш `LEGACY_CACHE_FILENAME`. Код перевіряє відповідність правилу, визначеного в (image-compress.mdc).
|
|
142
13
|
|
|
143
|
-
|
|
144
|
-
- **Проєкт з обробленими зображеннями (3.2+).** На диску є закомічений `.n-minify-image.tsv`, у `.gitignore` його немає, legacy-файла немає → exit-код `0`.
|
|
145
|
-
- **Незавершена міграція з 3.1 → 3.2.** На диску ще лежить `.minify-image-cache.tsv` → `fail` з готовим bash-snippet для очищення; exit-код `1`.
|
|
146
|
-
- **Помилково додано split-cache в `.gitignore`.** `.gitignore` містить `.n-minify-image.tsv` → `fail` з вимогою прибрати рядок; exit-код `1`.
|
|
147
|
-
- **Немає `package.json`.** Перша ж перевірка повертає `fail` і виконання обривається на guard-у; жодних інших перевірок не запускається; exit-код `1`.
|
|
14
|
+
## Поведінка
|
|
148
15
|
|
|
149
|
-
|
|
16
|
+
1. Зчитування рядків з `.gitignore`
|
|
17
|
+
2. Перевірка наявності кешу `HASH_CACHE_FILENAME` у `.gitignore`
|
|
18
|
+
3. Перевірка видалення застарілого кешу `LEGACY_CACHE_FILENAME`
|
|
19
|
+
4. Перевірка відповідності правилу `image-compress.mdc`
|
|
150
20
|
|
|
151
|
-
|
|
152
|
-
| ----------------------------------------------------------- | ----------------------------- |
|
|
153
|
-
| Наявність `package.json` | `package_setup.mjs` |
|
|
154
|
-
| `.n-minify-image.tsv` не в `.gitignore` | `package_setup.mjs` |
|
|
155
|
-
| `.minify-image-cache.tsv` відсутній (диск + `.gitignore`) | `package_setup.mjs` |
|
|
156
|
-
| `scripts.lint-image` коректний (без `--avif`) | Rego (`policy/package_json/`) |
|
|
157
|
-
| `bun run lint-image` в агрегованому `lint` | Rego (`policy/package_json/`) |
|
|
158
|
-
| `@nitra/minify-image` не в `dependencies`/`devDependencies` | Rego (`policy/package_json/`) |
|
|
21
|
+
## Публічний API
|
|
159
22
|
|
|
160
|
-
|
|
23
|
+
check — Перевіряє, чи відсутній у `.gitignore` файл `.n-minify-image.tsv` та чи видалено `.minify-image-cache.tsv`. Вказує, що CI-workflow для image не потрібен, оскільки лінтування зображень відбувається лише локально. (image-compress.mdc)
|
|
161
24
|
|
|
162
|
-
|
|
25
|
+
## Гарантії поведінки
|
|
163
26
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- `createCheckReporter` з `../../../scripts/lib/check-reporter.mjs`.
|
|
170
|
-
3. **Константи модульного рівня:**
|
|
171
|
-
- `HASH_CACHE_FILENAME = '.n-minify-image.tsv'`;
|
|
172
|
-
- `LEGACY_CACHE_FILENAME = '.minify-image-cache.tsv'`.
|
|
173
|
-
4. **Приватна `readGitignoreLines(cwd)`:** будує шлях `<cwd>/.gitignore`; якщо файла нема — `return null`; інакше читає UTF-8, розбиває по `\n`, `trim` кожного рядка, фільтрує порожні й ті, що починаються з `#`; повертає масив.
|
|
174
|
-
5. **Приватна `checkHashCacheNotIgnored(pass, fail, cwd)`:** читає рядки `.gitignore`; якщо вони є й містять `HASH_CACHE_FILENAME` — `fail` (з підказкою прибрати рядок), інакше `pass` («не в .gitignore — має бути в git»).
|
|
175
|
-
6. **Приватна `checkLegacyCacheRemoved(pass, fail, cwd)`:**
|
|
176
|
-
- якщо `<cwd>/<LEGACY_CACHE_FILENAME>` існує на диску — `fail` з готовим bash-snippet (`git rm --cached … 2>/dev/null || true && rm -f …`) і нагадуванням про `.gitignore`, потім `return`;
|
|
177
|
-
- інакше читає `.gitignore`; якщо містить `LEGACY_CACHE_FILENAME` — `fail` (прибрати застарілий ігнор), потім `return`;
|
|
178
|
-
- інакше `pass` («міграція на split-cache завершена»).
|
|
179
|
-
7. **Експортована `check(cwd = process.cwd())`:**
|
|
180
|
-
- `const reporter = createCheckReporter()`; деструктурує `{ pass, fail }`;
|
|
181
|
-
- якщо `<cwd>/package.json` не існує — `fail` («додай — image-compress.mdc») і одразу `return reporter.getExitCode()`;
|
|
182
|
-
- інакше `pass` («package.json є; структуру перевіряє npx @nitra/cursor fix → image_compress.package_json»);
|
|
183
|
-
- `await checkHashCacheNotIgnored(pass, fail, cwd)`;
|
|
184
|
-
- `await checkLegacyCacheRemoved(pass, fail, cwd)`;
|
|
185
|
-
- `return reporter.getExitCode()`.
|
|
186
|
-
8. **Інваріанти:**
|
|
187
|
-
- модуль не пише на диск нічого;
|
|
188
|
-
- `pass`/`fail` приймають лише `string` і викликаються рівно один раз на гілку логіки;
|
|
189
|
-
- функція `check` завжди повертає `number`, навіть на guard-шляху;
|
|
190
|
-
- усі шляхи будуються через `join(cwd, ...)`, ніяких рядкових конкатенацій.
|
|
191
|
-
9. **Текст повідомлень** містить посилання на правило `image-compress.mdc` і термін `split-cache 3.2.0`, щоб користувач у звіті бачив джерело вимоги.
|
|
27
|
+
- Read-only: файл не виконує операцій запису у файлову систему.
|
|
28
|
+
- За невдачі повертає значення помилки (`false`/`null`/`Err`) замість генерування винятку чи паніки.
|
|
29
|
+
- Кешує результати в межах одного прогону.
|
|
30
|
+
- Свідомо пропускає шляхи: `.git`.
|
|
31
|
+
- Не звертається до мережі.
|