@nitra/cursor 5.2.0 → 5.2.1

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.
@@ -1,140 +1,30 @@
1
- # `npm/rules/feedback/fix.mjs`
1
+ ---
2
+ docgen:
3
+ source: npm/rules/feedback/fix.mjs
4
+ crc: 12fc1644
5
+ score: 100
6
+ ---
2
7
 
3
- ## Огляд
4
-
5
- Файл є точкою входу (entry-point) для правила `feedback` у CLI-наборі `@nitra/cursor`. Він реалізує дві паралельні ролі того ж самого модуля:
6
-
7
- 1. **Library mode** — експортує функцію `run(ctx)`, яку викликають інші частини оркестратора (наприклад, агрегований `fix`/`lint`-прогін, де всі правила запускаються послідовно з шарінгом кешу обходу файлів `walkCache`).
8
- 2. **Standalone mode** — якщо файл стартує безпосередньо як CLI-скрипт (`bun rules/feedback/fix.mjs`), він виконується як повний аналог команди `npx @nitra/cursor fix feedback` із завантаженням конфігу, застосуванням whitelist та підсумком.
9
-
10
- Сам файл логіки правила не містить — він є тонким адаптером, що делегує роботу до спільного раннера `runStandardRule`. Стандартний потік правила, який запускається через цей адаптер: `applies → JS-concerns → policy → mdc-refs` (тобто перевіряється застосовність до проєкту, далі — JS-специфічні перевірки, далі — policy-шар, наприкінці — синхронізація посилань у відповідному `.mdc`-файлі).
11
-
12
- Модуль використовує `import.meta.dirname`, тому він повністю прив'язаний до місця свого розташування: каталог правила (`npm/rules/feedback/`) автоматично стає коренем, у якому раннер шукає `meta.json`, `feedback.mdc` та інші артефакти.
13
-
14
- ## Експорти / API
15
-
16
- | Експорт | Тип | Призначення |
17
- | ------- | --------------------------------- | ---------------------------------------------------------------------------------------------------- |
18
- | `run` | `function(ctx?): Promise<number>` | Library-точка входу правила. Викликається оркестратором; повертає exit-code (0 — OK, 1 — порушення). |
19
-
20
- Side-експортів немає. Default-експорту немає.
21
-
22
- Поведінка при прямому запуску файлу як CLI (через `process.exit(await runRuleCli(...))`) — це не експорт, а top-level side-effect, активний лише коли `isRunAsCli(import.meta.url)` повертає `true`.
23
-
24
- ## Функції
25
-
26
- ### `run(ctx)`
27
-
28
- ```js
29
- export function run(ctx)
30
- ```
31
-
32
- - **Призначення:** запустити правило `feedback` у library-режимі. Делегує всю роботу до `runStandardRule`, передаючи каталог поточного файлу як ідентифікатор правила.
33
- - **Параметри:**
34
- - `ctx` — `RuleContext | undefined`. Опціональний контекст прогону. Тип імпортується через JSDoc-посилання `import('../../scripts/lib/run-standard-rule.mjs').RuleContext`. Зокрема, контекст несе спільні структури між правилами (наприклад, `walkCache` — кеш обходу файлової системи, щоб не сканувати дерево кілька разів у разі прогону кількох правил поспіль). Якщо `ctx` не переданий, `runStandardRule` створює власний внутрішній контекст.
35
- - **Повертає:** `Promise<number>` — exit-code:
36
- - `0` — правило застосовне і порушень не знайдено, або правило не застосовне до поточного проєкту (`applies` повернув `false`);
37
- - `1` — знайдені порушення (policy / JS-concerns / mdc-refs).
38
- - **Side effects:** жодних прямих у цій функції. Опосередковано через `runStandardRule` можливі: читання файлів проєкту, читання `meta.json` і `feedback.mdc`, лог у stdout/stderr, мутація переданого `walkCache`.
39
- - **Винятки:** функція сама не кидає; будь-яка помилка приходить як rejected promise від `runStandardRule`.
40
-
41
- ### Top-level standalone-блок
42
-
43
- ```js
44
- if (isRunAsCli(import.meta.url)) {
45
- process.exit(await runRuleCli(import.meta.dirname))
46
- }
47
- ```
48
-
49
- - **Призначення:** перетворити цей же модуль на CLI-скрипт. Якщо файл був запущений напряму (а не імпортований), виконується повний CLI-цикл правила — еквівалент `npx @nitra/cursor fix feedback`.
50
- - **Виклик:** `runRuleCli(import.meta.dirname)` отримує абсолютний шлях до каталогу правила; всередині раннера це задає, який саме `meta.json`/`*.mdc` і `applies/policy/...`-функції підтягуються.
51
- - **Повертає / завершення:** результат `runRuleCli` (число) йде в `process.exit(...)`, тобто процес одразу завершується з відповідним exit-code. Це навмисно: standalone entry-point має повернути код виходу для CI/IDE-інтеграцій.
52
- - **Спеціальні маркери:**
53
- - `// eslint-disable-next-line n/no-process-exit, unicorn/no-process-exit` — свідома відмова від загальної заборони `process.exit` саме тут, бо це standalone-точка входу.
54
- - **Side effects:** завершує процес Node/Bun.
55
-
56
- ## Залежності
8
+ # fix.mjs
57
9
 
58
- Файл імпортує два внутрішні модулі (relative-шляхи, без зовнішніх npm-пакетів):
59
-
60
- | Імпорт | З файлу | Що використовується | Роль |
61
- | ----------------- | ----------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
62
- | `isRunAsCli` | `../../scripts/lib/run-rule-cli.mjs` | Функція-предикат | Визначає, чи цей `.mjs`-файл був запущений напряму як CLI (через `import.meta.url`), а не імпортований як модуль. |
63
- | `runRuleCli` | `../../scripts/lib/run-rule-cli.mjs` | Async-функція | Виконує повний CLI-цикл правила: завантаження конфігу, whitelist-фільтрацію, прогін стандартного раннера, форматування підсумку, повернення exit-code. |
64
- | `runStandardRule` | `../../scripts/lib/run-standard-rule.mjs` | Async-функція + JSDoc-тип `RuleContext` | Стандартний раннер для правил: `applies → JS-concerns → policy → mdc-refs`. Шукає артефакти у переданому каталозі. |
65
-
66
- Глобали з рантайму:
67
-
68
- - `import.meta.dirname` — абсолютний шлях каталогу поточного `.mjs`-файлу (Bun / Node ≥ 20.11). Використовується як «корінь правила».
69
- - `import.meta.url` — file-URL модуля; передається в `isRunAsCli` для надійного порівняння з `process.argv[1]`.
70
- - `process.exit` — викликається лише у standalone-гілці.
71
-
72
- Зовнішні пакети не імпортуються.
73
-
74
- ## Потік виконання / Використання
75
-
76
- ### Сценарій A — імпорт як library
77
-
78
- ```js
79
- import { run } from './npm/rules/feedback/fix.mjs'
80
-
81
- const code = await run(/* ctx */)
82
- if (code !== 0) {
83
- // правило знайшло порушення
84
- }
85
- ```
86
-
87
- Послідовність всередині:
88
-
89
- 1. Викликається `run(ctx)`.
90
- 2. `run` повертає `runStandardRule(import.meta.dirname, ctx)`.
91
- 3. Усередині `runStandardRule`:
92
- - перевіряє `applies` (чи правило застосовне до проєкту);
93
- - проганяє JS-concerns (lint/structure);
94
- - проганяє policy-перевірки;
95
- - звіряє `mdc-refs` (узгодженість посилань між кодом і `feedback.mdc`).
96
- 4. Повертається `0` або `1`.
97
-
98
- Top-level `if (isRunAsCli(...))` у цьому випадку не спрацьовує — `isRunAsCli(import.meta.url)` повертає `false`, бо стартова точка процесу — інший файл.
99
-
100
- ### Сценарій B — прямий запуск як CLI
101
-
102
- ```bash
103
- bun npm/rules/feedback/fix.mjs
104
- # або еквівалент:
105
- npx @nitra/cursor fix feedback
106
- ```
107
-
108
- Послідовність:
109
-
110
- 1. Node/Bun завантажує модуль; виконуються `import`-и.
111
- 2. Перевіряється `isRunAsCli(import.meta.url)` → `true`.
112
- 3. Викликається `await runRuleCli(import.meta.dirname)`. Цей раннер:
113
- - завантажує загальний конфіг проєкту;
114
- - застосовує whitelist (якщо в конфізі обмежений набір правил);
115
- - всередині все одно проганяє ту ж саму `runStandardRule`-логіку;
116
- - друкує форматований summary;
117
- - повертає exit-code.
118
- 4. `process.exit(code)` миттєво завершує процес із отриманим кодом, який потім читає CI/IDE.
119
-
120
- ### Чому дві ролі в одному файлі
10
+ ## Огляд
121
11
 
122
- Конвенція в `npm/rules/<id>/fix.mjs` дозволяє:
12
+ Модуль виконує задану перевірку, ініціалізуючи її з локального файлу конфігурації. При запуску як окрема програма, він завантажує конфігурацію, перевіряє білий список та надає звіт про результати виконання. Результат виконання правила повертається як код виходу.
123
13
 
124
- - оркестратору проганяти всі правила одним процесом, шарячи `walkCache` (швидко, для batch-режимів);
125
- - розробнику запустити **одне** правило точково з шелла без обгорток і отримати CI-сумісний exit-code.
14
+ ## Поведінка
126
15
 
127
- Жодного дублювання логіки немає — обидві гілки в кінцевому рахунку викликають один і той самий `runStandardRule`, просто standalone-гілка додає шар CLI-обгортки (`runRuleCli`).
16
+ 1. Викликається функція `run` для виконання правила.
17
+ 2. Виконання правила відбувається шляхом ініціалізації стандартного правила з директорії цього файлу.
18
+ 3. Якщо код виконується як окрема утиліта (standalone), ініціюється повний запуск правила.
19
+ 4. Запуск правила як окремої утиліти включає завантаження конфігурації, перевірку білого списку та підведення підсумків.
20
+ 5. Результат цього запуску повертається як код виходу.
128
21
 
129
- ## Rebuild Test
22
+ ## Публічний API
130
23
 
131
- Чи можна за цим документом без доступу до файлу відтворити модуль еквівалентної поведінки? Так:
24
+ run виконує послідовність перевірок: застосовує правила, аналізує JS-занепокоєння, порівнює з політикою та перевіряє посилання MDC.
132
25
 
133
- - ім'я експорту: `run`, сигнатура `(ctx) => Promise<number>`;
134
- - тіло: `return runStandardRule(import.meta.dirname, ctx)`;
135
- - top-level `if`: `isRunAsCli(import.meta.url)` → `process.exit(await runRuleCli(import.meta.dirname))`;
136
- - два імпорти з точно вказаних шляхів (`../../scripts/lib/run-rule-cli.mjs` для `isRunAsCli`/`runRuleCli`, `../../scripts/lib/run-standard-rule.mjs` для `runStandardRule`);
137
- - ESLint-disable коментар над `process.exit` для `n/no-process-exit` і `unicorn/no-process-exit`;
138
- - JSDoc-блок над `run` із посиланням на тип `RuleContext` через `import('...')`-нотацію.
26
+ ## Гарантії поведінки
139
27
 
140
- Усі ці елементи описані вище реконструкція еквівалентного файлу можлива.
28
+ - Read-only: файл не виконує операцій запису у файлову систему.
29
+ - Кешує результати в межах одного прогону.
30
+ - Не звертається до мережі.
@@ -1,25 +1,27 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/ga/fix.mjs
4
+ crc: 12fc1644
5
+ score: 100
6
+ ---
7
+
1
8
  # fix.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Цей файл запускає процес перевірки наявності та стану необхідних системних ресурсів. Він забезпечує швидку оцінку готовності системи до подальшої роботи, використовуючи кешовані дані для прискорення процесу. Результати перевірки використовуються для прийняття рішень щодо подальших дій.
12
+ Модуль відповідає за запуск механізму виконання стандартного правила. Він шукає та застосовує правила, використовуючи поточний каталог як джерело. При запуску як окрема програма, він ініціює виконання команди, необхідної для застосування цього правила.
6
13
 
7
14
  ## Поведінка
8
15
 
9
- 1. Ініціалізує контекст прогону.
10
- 2. Викликає стандартне правило, використовуючи контекст.
11
- 3. Якщо код виконується як окремий CLI-скрипт, то:
12
- 1. Викликає оркестрацію правил.
13
- 2. Повертає код завершення процесу.
16
+ 1. Викликає механізм виконання стандартного правила, використовуючи поточний каталог як джерело правил.
17
+ 2. Якщо скрипт виконується як окрема програма, запускає оркестрацію командного рядка для виконання правила.
14
18
 
15
19
  ## Публічний API
16
20
 
17
- - run — Запускає стандартне правило, враховуючи контекст та перетворюючи його на JS-коду, політику та посилання на MDC.
18
- - Library mode — Викликається через CLI-оркестрацію за допомогою імпорту та функції `run`.
21
+ run — виконує послідовність дій: застосовує правила, обробляє JS-занепокоєння, перевіряє політику та посилання MDC.
19
22
 
20
23
  ## Гарантії поведінки
21
24
 
22
- - Запускає процес.
23
- - Кеш зберігає результати попередніх прогонів.
24
- - Результат залежить від попередніх прогонів.
25
- - Немає взаємодії з мережею.
25
+ - Read-only: файл не виконує операцій запису у файлову систему.
26
+ - Кешує результати в межах одного прогону.
27
+ - Не звертається до мережі.
@@ -1,19 +1,22 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/ga/js/lint.mjs
4
+ crc: 428bf482
5
+ score: 100
6
+ ---
7
+
1
8
  # lint.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Файл `lint` делегує перевірку коду інструменту, який запускається з командного рядка. Він використовується для автоматизованої перевірки коду на відповідність певним правилам. Це забезпечує консистентність та якість коду в проєкті.
12
+ Делегує застосування правил зовнішньому інструменту командного рядка. Параметр `files` ігнорується, оскільки режим перевірки на рівні окремих файлів відсутній. Публічна функція `lint` повертає код виходу інструменту, який визначає успішність або невдачу перевірки.
6
13
 
7
14
  ## Поведінка
8
15
 
9
- 1. Запускає наявний CLI для перевірки правил.
10
- 2. Проводить аналіз всього репозиторію, ігноруючи вказаний список файлів.
11
- 3. Повертає код завершення процесу.
12
- 4. Не використовує кеш результатів.
13
- 5. Не здійснює взаємодії з мережею.
16
+ 1. Викликає зовнішній інструмент для перевірки коду.
17
+ 2. Повертає код виходу цього інструменту.
14
18
 
15
19
  ## Гарантії поведінки
16
20
 
17
- - Делегує правила до існуючого CLI.
18
- - Не враховує `files` в режимі per-file.
19
- - Не має кешування.
21
+ - Read-only: файл не виконує операцій запису у файлову систему.
22
+ - Не звертається до мережі.
@@ -1,32 +1,33 @@
1
+ ---
2
+ docgen:
3
+ source: npm/rules/ga/js/workflows.mjs
4
+ crc: a9296cf1
5
+ score: 100
6
+ ---
7
+
1
8
  # workflows.mjs
2
9
 
3
10
  ## Огляд
4
11
 
5
- Файл перевіряє GitHub Actions workflows на відповідність певним правилам та стандартам. Він забезпечує консистентність та якість workflow, виявляючи потенційні проблеми, такі як відсутність clean/lint workflow або використання непідтримуваних інструментів. Це частина автоматизованого процесу забезпечення дотримання найкращих практик при розробці GitHub Actions.
12
+ Модуль виявляє наявність інструменту `shellcheck` та підтверджує відповідність конфігурації проєкту правилам ga.mdc. Він перевіряє відповідність workflow-файлів Rego-полісі, наявність обов'язкових компонентів та коректність шляхів тригерів GitHub Actions. Модуль свідомо пропускає шляхи `.github` та `.git` під час перевірки.
6
13
 
7
14
  ## Поведінка
8
15
 
9
- - `checkShellcheckInstalled`: Перевіряє наявність бінарника `shellcheck` в системному PATH.
10
- - `checkGaWorkflowFiles`: Перевіряє наявність workflow-файлів з розширенням `.yml` та відсутність інших розширень.
11
- - `runAllGaRego`: Запускає Rego-перевірки для всіх workflow-файлів, використовуючи `conftest` для аналізу.
12
- - `check`: Координує всі перевірки, включаючи Rego-аналіз, перевірку workflow-структури та перевірку наявність файлів.
16
+ checkShellcheckInstalled перевіряє наявність бінарника `shellcheck` у системному шляху, щоб забезпечити узгодженість локальних та CI-перевірок (ga.mdc).
17
+ check виконує комплексну валідацію конфігурації проєкту щодо правил ga.mdc, включаючи структурну перевірку workflow-файлів за допомогою Rego-полісі, перевірку наявності обов'язкових компонентів, валідацію шляхів тригерів GitHub Actions, пошук залишків MegaLinter та перевірку наявності `shellcheck` (ga.mdc). При цьому ігнорує директорії `.github` та `.git`.
13
18
 
14
19
  ## Публічний API
15
20
 
16
- - checkShellcheckInstalled — Перевіряє наявність `shellcheck` у системі та зупиняє workflow, якщо його немає.
17
- - check — Перевіряє відповідність проєкту правилам валідації.
18
- - runAllGaRego Запускає Rego-перевірку правил, як перший етап валідації.
19
- - lint-ga — Запускає перевірку `bun lint-ga` з використанням `actionlint` та `zizmor`.
21
+ checkShellcheckInstalled — визначає, чи встановлено `shellcheck` у системному шляху. Це дозволяє `actionlint` запускати перевірки скриптів лише тоді, коли інструмент доступний локально.
22
+
23
+ checkпорівнює структуру проєкту з вимогами, визначеними у правилах (ga.mdc).
24
+
25
+ Plan B-патерн — виконує первинну перевірку структури робочого процесу за допомогою Rego-полісі. Потім виконує перевірки на рівні JavaScript, включаючи пошук файлів та конфігурацій. Команда `bun run lint-ga` повторно викликає цю ж перевірку, використовуючи зовнішні інструменти.
20
26
 
21
27
  ## Гарантії поведінки
22
28
 
23
- - Гарантується наявність файлів `package.json`, `.vscode/*` та `.github/zizmor.yml`.
24
- - Гарантується, що workflow використовує `actions/checkout@v6` перед локальними операціями.
25
- - Гарантується, що workflow використовує composite action `action.yml` з `npx @nitra/cursor`.
26
- - Гарантується, що workflow містить `clean-ga-workflows.yml`, `clean-merged-branch.yml`, `lint-ga.yml` та `git-ai.yml`.
27
- - Гарантується, що workflow використовує `concurrency` для паралельного виконання.
28
- - Гарантується, що workflow не містить `oven-sh/setup-bun`, `actions/cache`, `bun install` у `uses` або `run`.
29
- - Гарантується, що workflow не використовує shell-продовження `\` у `run`.
30
- - Гарантується, що workflow використовує `shellcheck` локально.
31
- - Гарантується, що workflow перевіряє наявність файлів за допомогою `git ls-files :(glob)` та `on.*.paths`.
32
- - Гарантується, що workflow перевіряє наявність файлів, що залишилися від MegaLinter.
29
+ - Read-only: файл не виконує операцій запису у файлову систему.
30
+ - Перехоплює помилки і не пропускає винятків назовні (fail-safe).
31
+ - За невдалої перевірки повертає `false`/`null` замість винятку.
32
+ - Свідомо пропускає шляхи: `.github`, `.git`.
33
+ - Не звертається до мережі.
@@ -1,264 +1,29 @@
1
- # tooling.mjs
2
-
3
- ## Огляд
4
-
5
- Модуль `npm/rules/graphql/js/tooling.mjs` — це **check-скрипт правила `graphql.mdc`**, який перевіряє, що репозиторій налаштований для роботи з GraphQL за наявності у коді tagged template literals `gql\`...\``.
6
-
7
- Логіка перевірки **умовна**:
8
-
9
- 1. Скрипт рекурсивно обходить дерево проєкту з кореня (`process.cwd()` за замовчуванням) і збирає файли-кандидати (`.vue`, `.js`, `.ts`, `.jsx`, `.tsx` тощо) — пропускаючи службові артефакти типу `.d.ts`, `auto-imports.d.ts` тощо.
10
- 2. Для кожного кандидата виконує AST-сканування (oxc-parser; для `.vue` — після витягування блоку `<script>`) у пошуках `gql` tagged template literal.
11
- 3. Якщо **жодного збігу не знайдено** — перевірка завершується успішно й нічого більше не вимагає.
12
- 4. Якщо `gql\`…\`` **знайдено хоча б в одному файлі** — модуль вимагає:
13
- - наявність файлу `.graphqlrc.yml` у корені репозиторію (GraphQL Config);
14
- - відповідність `.vscode/extensions.json` rego-пакету `graphql.vscode_extensions` (тобто рекомендацію розширення VS Code `graphql.vscode-graphql`).
15
-
16
- Модуль є частиною інфраструктури `n-cursor` для перевірок правил `.mdc` і дотримується контракту check-скрипта: повертає exit code `0` при успіху й `1` при порушенні.
17
-
18
- ## Експорти / API
19
-
20
- | Експорт | Тип | Призначення |
21
- | ----------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------- |
22
- | `GRAPHQL_RC_FILENAME` | `string` (const, `.graphqlrc.yml`) | Очікувана назва файлу GraphQL Config у корені проєкту (з `graphql.mdc`). |
23
- | `REQUIRED_GRAPHQL_VSCODE_EXTENSION` | `string` (const, `graphql.vscode-graphql`) | Ідентифікатор обов'язкового розширення VS Code, яке має бути в `recommendations`. |
24
- | `check(cwd?)` | `async function` | Основна точка входу — виконує всю перевірку правила `graphql.mdc` і повертає exit code. |
25
-
26
- Внутрішні (не експортовані) хелпери:
27
-
28
- - `collectScanCandidates(root, ignorePaths)` — збір абсолютних шляхів файлів для сканування.
29
- - `collectGqlHits(root, candidates)` — фільтрація кандидатів за наявністю `gql` tagged template.
30
- - `checkExtensionsRecommendation(pass, fail, cwd)` — делегування перевірки `.vscode/extensions.json` rego-пакету `graphql.vscode_extensions` через `conftest`.
31
-
32
- ## Функції
33
-
34
- ### `collectScanCandidates(root, ignorePaths)`
35
-
36
- **Сигнатура:**
37
-
38
- ```js
39
- async function collectScanCandidates(root: string, ignorePaths: string[]): Promise<string[]>
40
- ```
41
-
42
- **Параметри:**
43
-
44
- - `root` — абсолютний шлях до кореня репозиторію, з якого починається обхід.
45
- - `ignorePaths` — масив абсолютних шляхів каталогів, які повністю виключаються з обходу (формується через `loadCursorIgnorePaths`).
46
-
47
- **Що робить:**
48
-
49
- - Викликає `walkDir(root, visitor, ignorePaths)` (рекурсивний обхід файлової системи).
50
- - Для кожного відвіданого файлу обчислює відносний шлях від `root`, нормалізує роздільники (Windows `\` → POSIX `/`).
51
- - Застосовує два фільтри:
52
- - `shouldSkipFileForGqlScan(rel)` — пропуск службових файлів (`.d.ts`, `auto-imports.d.ts` тощо).
53
- - `isGqlScanSourceFile(rel)` — допуск лише відповідних розширень (Vue/JS/TS-сімейство).
54
- - Накопичує **абсолютні** шляхи прийнятих файлів у масив `candidates`.
55
-
56
- **Повертає:** `Promise<string[]>` — список абсолютних шляхів файлів-кандидатів.
57
-
58
- **Side effects:** читає метадані файлової системи (через `walkDir`); записів не робить.
59
-
60
1
  ---
61
-
62
- ### `collectGqlHits(root, candidates)`
63
-
64
- **Сигнатура:**
65
-
66
- ```js
67
- async function collectGqlHits(root: string, candidates: string[]): Promise<string[]>
68
- ```
69
-
70
- **Параметри:**
71
-
72
- - `root` — абсолютний шлях до кореня (для обчислення відносних шляхів у результаті).
73
- - `candidates` — список абсолютних шляхів файлів, отриманих від `collectScanCandidates`.
74
-
75
- **Що робить:**
76
-
77
- - Послідовно (`for-of` + `await`) для кожного абсолютного шляху:
78
- - обчислює відносний шлях і нормалізує роздільники до `/`;
79
- - читає вміст файлу через `readFile(absPath, 'utf8')`;
80
- - викликає `sourceFileHasGqlTaggedTemplate(content, rel)` — парсер AST oxc, що враховує особливості `.vue` (витягування `<script>`);
81
- - якщо результат `true` — додає **відносний** шлях до результуючого масиву `hits`.
82
-
83
- **Повертає:** `Promise<string[]>` — відносні шляхи файлів, у яких знайдено хоча б одне `gql` tagged template.
84
-
85
- **Side effects:** читання вмісту файлів з диска. Запис відсутній.
86
-
2
+ docgen:
3
+ source: npm/rules/graphql/js/tooling.mjs
4
+ crc: eb6b4713
5
+ score: 100
87
6
  ---
88
7
 
89
- ### `checkExtensionsRecommendation(pass, fail, cwd)`
90
-
91
- **Сигнатура:**
92
-
93
- ```js
94
- function checkExtensionsRecommendation(
95
- pass: (msg: string) => void,
96
- fail: (msg: string) => void,
97
- cwd: string
98
- ): void
99
- ```
100
-
101
- **Параметри:**
102
-
103
- - `pass` — функція-репортер «успішно» (отримана з `createCheckReporter()`).
104
- - `fail` — функція-репортер «порушення».
105
- - `cwd` — абсолютний корінь репозиторію.
106
-
107
- **Що робить:**
108
-
109
- 1. Формує відносний (`.vscode/extensions.json`) і абсолютний шляхи до файлу VS Code-конфігу.
110
- 2. Якщо файл **не існує** (`existsSync`) — викликає `fail(...)` з повідомленням про те, що треба створити файл і додати `graphql.vscode-graphql` у `recommendations`, посилаючись на `graphql.mdc`. Виходить.
111
- 3. Інакше викликає `runConftestBatch({ policyDirRel: 'graphql/vscode_extensions', namespace: 'graphql.vscode_extensions', files: [pathAbs] })` — делегує перевірку rego-пакету conftest-у.
112
- 4. Якщо `violations.length === 0` — викликає `pass(...)` з повідомленням про відповідність. Інакше — для кожного порушення `v` викликає `fail(v.message)`.
113
-
114
- **Повертає:** нічого (`void`). Результати фіксуються через `pass` / `fail`.
115
-
116
- **Side effects:**
117
-
118
- - читання `.vscode/extensions.json` через зовнішній conftest-процес;
119
- - виклик `conftest` (binary) усередині `runConftestBatch`;
120
- - зміна стану внутрішнього reporter-у (накопичення успіхів/порушень).
121
-
122
- **Виклик умовний:** виконується лише після того, як основна функція `check` виявила `gql` у дереві.
123
-
124
- ---
125
-
126
- ### `check(cwd = process.cwd())`
127
-
128
- **Сигнатура:**
129
-
130
- ```js
131
- export async function check(cwd?: string): Promise<number>
132
- ```
133
-
134
- **Параметри:**
135
-
136
- - `cwd` — _необов'язковий_ абсолютний шлях до кореня репозиторію. За замовчуванням `process.cwd()`.
137
-
138
- **Що робить (потік):**
139
-
140
- 1. Створює репортер `createCheckReporter()` і деструктурує з нього `pass`, `fail`.
141
- 2. Завантажує список ігнорованих шляхів через `loadCursorIgnorePaths(root)`.
142
- 3. Викликає `collectScanCandidates(root, ignorePaths)` — отримує список файлів-кандидатів.
143
- 4. Викликає `collectGqlHits(root, candidates)` — отримує файли з `gql`.
144
- 5. **Розгалуження:**
145
- - Якщо `hits.length === 0` — викликає `pass(...)` з повідомленням «немає `gql\`…\``у джерелах, переглянуто N файлів —`.graphqlrc.yml`не вимагається» і **повертає**`reporter.getExitCode()`(зазвичай`0`).
146
- - Інакше викликає `pass(...)` зі звітом про N файлів (з перших 5 з суфіксом `…` якщо більше).
147
- 6. Перевіряє наявність `GRAPHQL_RC_FILENAME` (`.graphqlrc.yml`) у корені через `existsSync`:
148
- - Існує → `pass('.graphqlrc.yml існує')`.
149
- - Не існує → `fail(...)` з вимогою додати GraphQL Config (з посиланням на `graphql.mdc`).
150
- 7. Викликає `checkExtensionsRecommendation(pass, fail, root)` для перевірки `.vscode/extensions.json`.
151
- 8. Повертає `reporter.getExitCode()`: `0` — усі перевірки пройдені, `1` — є хоча б одне порушення.
152
-
153
- **Повертає:** `Promise<number>` — exit code (`0` — OK, `1` — порушення).
154
-
155
- **Side effects:**
156
-
157
- - читання файлової системи (метадані + вміст файлів кандидатів);
158
- - читання `.cursor/...` ignore-конфігу;
159
- - читання `.vscode/extensions.json` (опосередковано через conftest);
160
- - запуск процесу `conftest` через `runConftestBatch`;
161
- - мутація стану внутрішнього reporter-у (накопичення pass/fail-повідомлень).
162
-
163
- ## Залежності
164
-
165
- ### Node.js builtins
166
-
167
- | Модуль | Що використовується | Призначення |
168
- | ------------------ | ------------------- | ---------------------------------------------------------------------------- |
169
- | `node:fs` | `existsSync` | Синхронна перевірка наявності `.graphqlrc.yml` та `.vscode/extensions.json`. |
170
- | `node:fs/promises` | `readFile` | Асинхронне читання вмісту файлів-кандидатів. |
171
- | `node:path` | `join`, `relative` | Збирання абсолютних шляхів і обчислення відносних шляхів від кореня. |
172
-
173
- ### Внутрішні модулі репозиторію
174
-
175
- - `../../../scripts/lib/check-reporter.mjs` — `createCheckReporter`: фабрика репортера зі стандартним інтерфейсом `pass` / `fail` / `getExitCode()`.
176
- - `../lib/graphql-gql-scan.mjs`:
177
- - `isGqlScanSourceFile(rel)` — предикат «це source-файл, який потенційно містить `gql`» (за розширенням);
178
- - `shouldSkipFileForGqlScan(rel)` — предикат «цей файл слід ігнорувати при скануванні» (`.d.ts`, `auto-imports.d.ts` тощо);
179
- - `sourceFileHasGqlTaggedTemplate(content, rel)` — AST-перевірка на наявність `gql\`...\``(через oxc-parser; для`.vue`— після витягування`<script>`).
180
- - `../../../scripts/lib/load-cursor-config.mjs` — `loadCursorIgnorePaths(root)`: повертає абсолютні шляхи каталогів, повністю виключених з обходу (узгоджено з іншими check-скриптами).
181
- - `../../../scripts/lib/run-conftest-batch.mjs` — `runConftestBatch({ policyDirRel, namespace, files })`: запускає `conftest` з rego-пакетом і повертає масив `violations` (об'єкти з `.message`).
182
- - `../../../scripts/utils/walkDir.mjs` — `walkDir(root, visitor, ignorePaths)`: рекурсивний обхід файлової системи з підтримкою списку ігнорування.
183
-
184
- ### Зовнішні артефакти (не імпортуються, але потрібні в runtime)
185
-
186
- - **`conftest`** як CLI-binary (запускається з `runConftestBatch`).
187
- - **Rego-політика** в `graphql/vscode_extensions` з namespace `graphql.vscode_extensions` (перевіряє `.vscode/extensions.json`).
188
- - **`.cursor/ignore`-конфіг** у корені (читається `loadCursorIgnorePaths`).
189
- - **`graphql.mdc`** — правило, яке цей check реалізує.
190
-
191
- ## Потік виконання / Використання
192
-
193
- ### Запуск як check
194
-
195
- Модуль використовується з єдиною експортованою функцією `check`:
196
-
197
- ```js
198
- import { check } from 'npm/rules/graphql/js/tooling.mjs'
199
-
200
- const exitCode = await check() // або await check('/absolute/path/to/repo')
201
- process.exit(exitCode)
202
- ```
203
-
204
- Типово викликається диспетчером check-скриптів інфраструктури `n-cursor` (наприклад, із `npm/scripts/...`), який отримує exit code й агрегує результати по всіх правилах `.mdc`.
8
+ # tooling.mjs
205
9
 
206
- ### Послідовність дій усередині `check`
10
+ ## Огляд
207
11
 
208
- ```
209
- process.cwd() (або переданий cwd)
210
-
211
-
212
- createCheckReporter() ──► { pass, fail, getExitCode }
213
-
214
-
215
- loadCursorIgnorePaths(root) ──► ignorePaths
216
-
217
-
218
- collectScanCandidates(root, ignorePaths)
219
- │ walkDir(root, visitor, ignorePaths)
220
- │ filter: !shouldSkipFileForGqlScan && isGqlScanSourceFile
221
-
222
- candidates: string[]
223
-
224
-
225
- collectGqlHits(root, candidates)
226
- │ for each: readFile + sourceFileHasGqlTaggedTemplate (oxc-parser AST)
227
-
228
- hits: string[]
229
-
230
- ├── hits.length === 0 ──► pass("немає gql у джерелах") ──► return 0
231
-
232
- └── hits.length > 0
233
-
234
- ├── pass("Знайдено gql у N файлі(ах): ...")
235
-
236
- ├── existsSync(.graphqlrc.yml)
237
- │ ├── true ──► pass(".graphqlrc.yml існує")
238
- │ └── false ──► fail("Відсутній .graphqlrc.yml ...")
239
-
240
- ├── checkExtensionsRecommendation(pass, fail, root)
241
- │ ├── !existsSync(.vscode/extensions.json) ──► fail(...)
242
- │ └── runConftestBatch(graphql/vscode_extensions)
243
- │ ├── violations.length === 0 ──► pass(...)
244
- │ └── for v of violations: fail(v.message)
245
-
246
- └── return reporter.getExitCode() (0 або 1)
247
- ```
12
+ Визначає ім'я файлу конфігурації (`GRAPHQL_RC_FILENAME` = ".graphqlrc.yml") та обов'язкове розширення VS Code (`REQUIRED_GRAPHQL_VSCODE_EXTENSION` = "graphql.vscode-graphql"). Перевіряє наявність конфігурації в `extensions.json` (конфігурація, на яку спирається код) та підтверджує необхідність розширення для роботи з GraphQL (graphql.mdc).
248
13
 
249
- ### Семантика повідомлень
14
+ ## Поведінка
250
15
 
251
- - `pass` інформативне повідомлення про успішну перевірку (логнеться як OK, не впливає на exit code).
252
- - `fail` повідомлення про порушення; навіть одне `fail` робить `getExitCode()` рівним `1`.
16
+ GRAPHQL_RC_FILENAME: Повертає ім'я файлу конфігурації GraphQL.
17
+ REQUIRED_GRAPHQL_VSCODE_EXTENSION: Повертає ім'я розширення VS Code, необхідне для GraphQL.
18
+ check: Перевіряє наявність `gql` tagged template у джерелах. Якщо знайдено, вимагає наявності `.graphqlrc.yml` та валідує `.vscode/extensions.json` щодо `graphql.vscode-graphql` (graphql.mdc).
253
19
 
254
- ### Чому перевірка умовна
20
+ ## Публічний API
255
21
 
256
- `graphql.mdc` вимагає `.graphqlrc.yml` і VS Code-розширення `graphql.vscode-graphql` **лише** для проєктів, де реально використовуються `gql` tagged template literals. У монорепо це дозволяє не «спамити» правилом workspace-и, що не торкаються GraphQL check спочатку доводить релевантність (`hits.length > 0`), і лише потім вимагає інфраструктуру.
22
+ GRAPHQL_RC_FILENAME вказує на файл конфігурації GraphQL у корені проєкту (graphql.mdc).
23
+ REQUIRED_GRAPHQL_VSCODE_EXTENSION — вимагає встановлення розширення `graphql.vscode-graphql` для роботи з graphql.mdc.
24
+ check — перевіряє наявність файлу `.graphqlrc.yml` та розширення `graphql.vscode-graphql` при використанні тегів GraphQL.
257
25
 
258
- ### Обмеження та особливості
26
+ ## Гарантії поведінки
259
27
 
260
- - Шляхи в `hits` та в попередженнях завжди **відносні** до `root`, з POSIX-роздільниками `/` (навіть на Windows).
261
- - Перші 5 файлів-збігів показуються у повідомленні `pass`; решта приховується за суфіксом `…`.
262
- - Якщо `gql` знайдено, але `.vscode/extensions.json` відсутній — це порушення, незалежне від rego-перевірки (тобто `fail` без виклику conftest).
263
- - `collectGqlHits` читає файли **послідовно** (без `Promise.all`) — це навмисно, щоб не перевантажувати I/O при великих репозиторіях.
264
- - Виявлення `gql` — на рівні AST (oxc-parser), а не регулярних виразів; рядкові збіги типу `// gql\`...\`` у коментарі не дають false-positive.
28
+ - Read-only: файл не виконує операцій запису у файлову систему.
29
+ - Не звертається до мережі.