@nitra/cursor 12.8.3 → 12.8.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/package.json +1 -1
- package/rules/js/docs/index.md +3 -3
- package/rules/js/docs/main.md +6 -6
- package/rules/js/js/docs/check.md +12 -17
- package/rules/js/js/docs/index.md +4 -4
- package/rules/js/js/docs/tooling.md +8 -8
- package/rules/js/js/docs/utils_imports.md +21 -200
- package/rules/npm-module/js/docs/index.md +5 -5
- package/rules/npm-module/js/docs/rule_meta.md +13 -13
- package/rules/npm-module/js/docs/skill_meta.md +19 -9
- package/rules/npm-module/js/rule_meta.mjs +9 -9
- package/rules/npm-module/js/skill_meta.mjs +6 -6
- package/rules/test/js/docs/index.md +7 -7
- package/rules/test/js/docs/stryker_config.md +18 -35
- package/rules/test/js/docs/vitest-config-pool-forks.md +14 -12
- package/schemas/v8r-catalog.json +4 -4
- package/scripts/docs/index.md +16 -16
- package/scripts/docs/sync-setup-bun-deps-action.md +13 -14
- package/scripts/lib/check-mdc-template-refs.mjs +2 -2
- package/scripts/lib/docs/check-mdc-template-refs.md +12 -214
- package/scripts/lib/docs/index.md +36 -36
- package/scripts/lib/docs/mirror-parity.md +18 -157
- package/scripts/lib/docs/rule-meta.md +19 -22
- package/scripts/lib/docs/run-rule.md +11 -11
- package/scripts/lib/docs/skill-meta.md +17 -19
- package/scripts/lib/docs/timing-summary.md +6 -6
- package/scripts/lib/mirror-parity.mjs +1 -1
- package/scripts/lib/rule-meta.mjs +1 -1
- package/scripts/lib/run-rule.mjs +4 -4
- package/scripts/lib/skill-meta.mjs +1 -1
- package/scripts/utils/docs/index.md +14 -14
- package/scripts/utils/docs/resolve-js-root.md +12 -13
- /package/rules/abie/{meta.json → main.json} +0 -0
- /package/rules/abie/{abie.mdc → main.mdc} +0 -0
- /package/rules/adr/{meta.json → main.json} +0 -0
- /package/rules/adr/{adr.mdc → main.mdc} +0 -0
- /package/rules/bun/{meta.json → main.json} +0 -0
- /package/rules/bun/{bun.mdc → main.mdc} +0 -0
- /package/rules/capacitor/{meta.json → main.json} +0 -0
- /package/rules/capacitor/{capacitor.mdc → main.mdc} +0 -0
- /package/rules/changelog/{meta.json → main.json} +0 -0
- /package/rules/changelog/{changelog.mdc → main.mdc} +0 -0
- /package/rules/ci4/{meta.json → main.json} +0 -0
- /package/rules/ci4/{ci4.mdc → main.mdc} +0 -0
- /package/rules/doc-files/{meta.json → main.json} +0 -0
- /package/rules/doc-files/{doc-files.mdc → main.mdc} +0 -0
- /package/rules/docker/{meta.json → main.json} +0 -0
- /package/rules/docker/{docker.mdc → main.mdc} +0 -0
- /package/rules/efes/{meta.json → main.json} +0 -0
- /package/rules/efes/{efes.mdc → main.mdc} +0 -0
- /package/rules/feedback/{meta.json → main.json} +0 -0
- /package/rules/feedback/{feedback.mdc → main.mdc} +0 -0
- /package/rules/ga/{meta.json → main.json} +0 -0
- /package/rules/ga/{ga.mdc → main.mdc} +0 -0
- /package/rules/graphql/{meta.json → main.json} +0 -0
- /package/rules/graphql/{graphql.mdc → main.mdc} +0 -0
- /package/rules/hasura/{meta.json → main.json} +0 -0
- /package/rules/hasura/{hasura.mdc → main.mdc} +0 -0
- /package/rules/image-avif/{meta.json → main.json} +0 -0
- /package/rules/image-avif/{image-avif.mdc → main.mdc} +0 -0
- /package/rules/image-compress/{meta.json → main.json} +0 -0
- /package/rules/image-compress/{image-compress.mdc → main.mdc} +0 -0
- /package/rules/js/{meta.json → main.json} +0 -0
- /package/rules/js/{js.mdc → main.mdc} +0 -0
- /package/rules/js-bun-db/{meta.json → main.json} +0 -0
- /package/rules/js-bun-db/{js-bun-db.mdc → main.mdc} +0 -0
- /package/rules/js-bun-redis/{meta.json → main.json} +0 -0
- /package/rules/js-bun-redis/{js-bun-redis.mdc → main.mdc} +0 -0
- /package/rules/js-mssql/{meta.json → main.json} +0 -0
- /package/rules/js-mssql/{js-mssql.mdc → main.mdc} +0 -0
- /package/rules/js-run/{meta.json → main.json} +0 -0
- /package/rules/js-run/{js-run.mdc → main.mdc} +0 -0
- /package/rules/k8s/{meta.json → main.json} +0 -0
- /package/rules/k8s/{k8s.mdc → main.mdc} +0 -0
- /package/rules/nginx-default-tpl/{meta.json → main.json} +0 -0
- /package/rules/nginx-default-tpl/{nginx-default-tpl.mdc → main.mdc} +0 -0
- /package/rules/npm-module/{meta.json → main.json} +0 -0
- /package/rules/npm-module/{npm-module.mdc → main.mdc} +0 -0
- /package/rules/php/{meta.json → main.json} +0 -0
- /package/rules/php/{php.mdc → main.mdc} +0 -0
- /package/rules/python/{meta.json → main.json} +0 -0
- /package/rules/python/{python.mdc → main.mdc} +0 -0
- /package/rules/rego/{meta.json → main.json} +0 -0
- /package/rules/rego/{rego.mdc → main.mdc} +0 -0
- /package/rules/release/{meta.json → main.json} +0 -0
- /package/rules/release/{release.mdc → main.mdc} +0 -0
- /package/rules/rust/{meta.json → main.json} +0 -0
- /package/rules/rust/{rust.mdc → main.mdc} +0 -0
- /package/rules/security/{meta.json → main.json} +0 -0
- /package/rules/security/{security.mdc → main.mdc} +0 -0
- /package/rules/style/{meta.json → main.json} +0 -0
- /package/rules/style/{style.mdc → main.mdc} +0 -0
- /package/rules/tauri/{meta.json → main.json} +0 -0
- /package/rules/tauri/{tauri.mdc → main.mdc} +0 -0
- /package/rules/test/{meta.json → main.json} +0 -0
- /package/rules/test/{test.mdc → main.mdc} +0 -0
- /package/rules/text/{meta.json → main.json} +0 -0
- /package/rules/text/{text.mdc → main.mdc} +0 -0
- /package/rules/tool-surface/{meta.json → main.json} +0 -0
- /package/rules/tool-surface/{tool-surface.mdc → main.mdc} +0 -0
- /package/rules/vue/{meta.json → main.json} +0 -0
- /package/rules/vue/{vue.mdc → main.mdc} +0 -0
- /package/rules/worktree/{meta.json → main.json} +0 -0
- /package/rules/worktree/{worktree.mdc → main.mdc} +0 -0
- /package/skills/adr-normalize/{meta.json → main.json} +0 -0
- /package/skills/coverage-fix/{meta.json → main.json} +0 -0
- /package/skills/doc-aggregate/{meta.json → main.json} +0 -0
- /package/skills/doc-files/{meta.json → main.json} +0 -0
- /package/skills/lint/{meta.json → main.json} +0 -0
- /package/skills/llm-patch/{meta.json → main.json} +0 -0
- /package/skills/publish-telegram/{meta.json → main.json} +0 -0
- /package/skills/start-check/{meta.json → main.json} +0 -0
- /package/skills/taze/{meta.json → main.json} +0 -0
|
@@ -6,40 +6,40 @@ resource: npm/scripts/lib/
|
|
|
6
6
|
|
|
7
7
|
# npm/scripts/lib
|
|
8
8
|
|
|
9
|
-
| Файл
|
|
10
|
-
|
|
11
|
-
| [assert-project-root.mjs](assert-project-root.md)
|
|
12
|
-
| [changed-files.mjs](changed-files.md)
|
|
13
|
-
| [check-mdc-template-refs.mjs](check-mdc-template-refs.md)
|
|
14
|
-
| [check-reporter.mjs](check-reporter.md)
|
|
15
|
-
| [diff-added-lines.mjs](diff-added-lines.md)
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
|---|---|
|
|
11
|
+
| [assert-project-root.mjs](assert-project-root.md) | JS Module |
|
|
12
|
+
| [changed-files.mjs](changed-files.md) | JS Module |
|
|
13
|
+
| [check-mdc-template-refs.mjs](check-mdc-template-refs.md) | JS Module |
|
|
14
|
+
| [check-reporter.mjs](check-reporter.md) | JS Module |
|
|
15
|
+
| [diff-added-lines.mjs](diff-added-lines.md) | JS Module |
|
|
16
16
|
| [discover-check-rules-from-cursor.mjs](discover-check-rules-from-cursor.md) | JS Module |
|
|
17
|
-
| [discover-checkable-rules.mjs](discover-checkable-rules.md)
|
|
18
|
-
| [ensure-tool.mjs](ensure-tool.md)
|
|
19
|
-
| [generated-markdown.mjs](generated-markdown.md)
|
|
20
|
-
| [gha-workflow.mjs](gha-workflow.md)
|
|
21
|
-
| [inline-template-links.mjs](inline-template-links.md)
|
|
22
|
-
| [list-project-rules-mdc.mjs](list-project-rules-mdc.md)
|
|
23
|
-
| [list-rule-ids.mjs](list-rule-ids.md)
|
|
24
|
-
| [load-cursor-config.mjs](load-cursor-config.md)
|
|
25
|
-
| [mirror-parity.mjs](mirror-parity.md)
|
|
26
|
-
| [read-n-cursor-config-lite.mjs](read-n-cursor-config-lite.md)
|
|
27
|
-
| [resolve-target-files.mjs](resolve-target-files.md)
|
|
28
|
-
| [root-notice.mjs](root-notice.md)
|
|
29
|
-
| [rule-meta-helpers.mjs](rule-meta-helpers.md)
|
|
30
|
-
| [rule-meta.mjs](rule-meta.md)
|
|
31
|
-
| [rule-predicates.mjs](rule-predicates.md)
|
|
32
|
-
| [run-conftest-batch.mjs](run-conftest-batch.md)
|
|
33
|
-
| [run-lint-step.mjs](run-lint-step.md)
|
|
34
|
-
| [run-lint.mjs](run-lint.md)
|
|
35
|
-
| [run-rule-cli.mjs](run-rule-cli.md)
|
|
36
|
-
| [run-rule.mjs](run-rule.md)
|
|
37
|
-
| [run-standard-lint.mjs](run-standard-lint.md)
|
|
38
|
-
| [run-standard-rule.mjs](run-standard-rule.md)
|
|
39
|
-
| [skill-meta.mjs](skill-meta.md)
|
|
40
|
-
| [sync-gitignore-worktree.mjs](sync-gitignore-worktree.md)
|
|
41
|
-
| [template.mjs](template.md)
|
|
42
|
-
| [timing-summary.mjs](timing-summary.md)
|
|
43
|
-
| [workspaces.mjs](workspaces.md)
|
|
44
|
-
| [worktree-notice.mjs](worktree-notice.md)
|
|
45
|
-
| [worktree.mjs](worktree.md)
|
|
17
|
+
| [discover-checkable-rules.mjs](discover-checkable-rules.md) | JS Module |
|
|
18
|
+
| [ensure-tool.mjs](ensure-tool.md) | JS Module |
|
|
19
|
+
| [generated-markdown.mjs](generated-markdown.md) | JS Module |
|
|
20
|
+
| [gha-workflow.mjs](gha-workflow.md) | JS Module |
|
|
21
|
+
| [inline-template-links.mjs](inline-template-links.md) | JS Module |
|
|
22
|
+
| [list-project-rules-mdc.mjs](list-project-rules-mdc.md) | JS Module |
|
|
23
|
+
| [list-rule-ids.mjs](list-rule-ids.md) | JS Module |
|
|
24
|
+
| [load-cursor-config.mjs](load-cursor-config.md) | JS Module |
|
|
25
|
+
| [mirror-parity.mjs](mirror-parity.md) | JS Module |
|
|
26
|
+
| [read-n-cursor-config-lite.mjs](read-n-cursor-config-lite.md) | JS Module |
|
|
27
|
+
| [resolve-target-files.mjs](resolve-target-files.md) | JS Module |
|
|
28
|
+
| [root-notice.mjs](root-notice.md) | JS Module |
|
|
29
|
+
| [rule-meta-helpers.mjs](rule-meta-helpers.md) | JS Module |
|
|
30
|
+
| [rule-meta.mjs](rule-meta.md) | JS Module |
|
|
31
|
+
| [rule-predicates.mjs](rule-predicates.md) | JS Module |
|
|
32
|
+
| [run-conftest-batch.mjs](run-conftest-batch.md) | JS Module |
|
|
33
|
+
| [run-lint-step.mjs](run-lint-step.md) | JS Module |
|
|
34
|
+
| [run-lint.mjs](run-lint.md) | JS Module |
|
|
35
|
+
| [run-rule-cli.mjs](run-rule-cli.md) | JS Module |
|
|
36
|
+
| [run-rule.mjs](run-rule.md) | JS Module |
|
|
37
|
+
| [run-standard-lint.mjs](run-standard-lint.md) | JS Module |
|
|
38
|
+
| [run-standard-rule.mjs](run-standard-rule.md) | JS Module |
|
|
39
|
+
| [skill-meta.mjs](skill-meta.md) | JS Module |
|
|
40
|
+
| [sync-gitignore-worktree.mjs](sync-gitignore-worktree.md) | JS Module |
|
|
41
|
+
| [template.mjs](template.md) | JS Module |
|
|
42
|
+
| [timing-summary.mjs](timing-summary.md) | JS Module |
|
|
43
|
+
| [workspaces.mjs](workspaces.md) | JS Module |
|
|
44
|
+
| [worktree-notice.mjs](worktree-notice.md) | JS Module |
|
|
45
|
+
| [worktree.mjs](worktree.md) | JS Module |
|
|
@@ -3,171 +3,32 @@ type: JS Module
|
|
|
3
3
|
title: mirror-parity.mjs
|
|
4
4
|
resource: npm/scripts/lib/mirror-parity.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: d2140a00
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- дзеркало лежить у `.cursor/rules/n-<id>.mdc` і повинно бути результатом застосування трансформу `inlineTemplateLinks` до канону (тобто посилання на шаблони мають бути вставлені «інлайном»).
|
|
13
|
+
Модуль забезпечує паралельність (parity) дзеркал правил. Він порівнює вміст дзеркала `.cursor/rules/n-<id>.mdc` з канонічним вмістом `npm/rules/<id>/<id>.mdc`, який містить вбудовані шаблони (inlined-шаблони). Це гарантує, що локальні копії правил відповідають централізованим, трансформованим версіям, виявляючи дрейф, що виникає при зміні канонічного `.mdc` без регенерації дзеркала.
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
## Поведінка
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- виявляє ідентифікатори дрейфних правил (де `actual ≠ expected`).
|
|
17
|
+
listManagedMirrors
|
|
18
|
+
Визначає список керованих дзеркал правил, які мають канонічне джерело у `npm/rules`.
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
expectedMirrorContent
|
|
21
|
+
Формує очікуваний вміст дзеркала, застосовуючи трансформацію до канонічного вмісту.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
findMirrorDrift
|
|
24
|
+
Виявляє і повертає список ідентифікаторів дзеркал, вміст яких відрізняється від очікуваного канонічного.
|
|
23
25
|
|
|
24
|
-
|
|
26
|
+
## Публічний API
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
listManagedMirrors — перераховує дзеркала, які мають визначене основне джерело, і ігнорує зовнішні.
|
|
29
|
+
expectedMirrorContent — визначає, яким має бути вміст дзеркала, використовуючи основне джерело з вбудованими шаблонами.
|
|
30
|
+
findMirrorDrift — виявляє ідентифікатори дзеркал, чий фактичний вміст відрізняється від очікуваного.
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
## Гарантії поведінки
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
### `listManagedMirrors(repoRoot)`
|
|
35
|
-
|
|
36
|
-
Сигнатура: `function listManagedMirrors(repoRoot: string): { id: string, mirrorPath: string, canonicalPath: string }[]`
|
|
37
|
-
|
|
38
|
-
Параметри:
|
|
39
|
-
|
|
40
|
-
- `repoRoot` — абсолютний шлях до кореня репозиторію (директорія, у якій лежать `.cursor/` та `npm/`).
|
|
41
|
-
|
|
42
|
-
Повертає масив об'єктів-описів дзеркал, де:
|
|
43
|
-
|
|
44
|
-
- `id` — ідентифікатор правила без префіксу `n-` і без розширення `.mdc` (наприклад, для файлу `n-bun.mdc` → `bun`);
|
|
45
|
-
- `mirrorPath` — абсолютний шлях до файлу дзеркала всередині `.cursor/rules/`;
|
|
46
|
-
- `canonicalPath` — абсолютний шлях до канонічного `.mdc` всередині `npm/rules/<id>/`.
|
|
47
|
-
|
|
48
|
-
Алгоритм:
|
|
49
|
-
|
|
50
|
-
1. Будує шлях до `.cursor/rules`.
|
|
51
|
-
2. Якщо такої директорії не існує (`existsSync` false) — повертає порожній масив (раннє повернення, безпечне для свіжих репо).
|
|
52
|
-
3. Зчитує перелік файлів директорії синхронно (`readdirSync`).
|
|
53
|
-
4. Фільтрує файли: повинні починатися з префіксу `'n-'` (константа `MIRROR_PREFIX`) і завершуватися розширенням `'.mdc'` (константа `MDC_EXT`).
|
|
54
|
-
5. Мапить кожен файл у об'єкт із обчисленими шляхами: `id` отримується вирізанням префіксу і розширення (`f.slice(MIRROR_PREFIX.length, -MDC_EXT.length)`).
|
|
55
|
-
6. Залишає лише ті записи, для яких реально існує канонічне джерело `canonicalPath` (друга фільтрація через `existsSync`). Це дозволяє пропускати «зовнішні» дзеркала, які не мають канону в монорепо.
|
|
56
|
-
|
|
57
|
-
Side effects: лише читання директорії з диску (синхронні `existsSync`, `readdirSync`). Жодних записів, мережевих викликів, мутацій глобального стану.
|
|
58
|
-
|
|
59
|
-
Помилки: якщо файлова система кине помилку під час `readdirSync` (наприклад, права доступу) — вона прокинеться вгору; для типового сценарію відсутності директорії `.cursor/rules` функція не падає (гард через `existsSync`).
|
|
60
|
-
|
|
61
|
-
### `expectedMirrorContent(canonicalPath)`
|
|
62
|
-
|
|
63
|
-
Сигнатура: `function expectedMirrorContent(canonicalPath: string): Promise<string>`
|
|
64
|
-
|
|
65
|
-
Параметри:
|
|
66
|
-
|
|
67
|
-
- `canonicalPath` — абсолютний шлях до канонічного `.mdc`-файлу (`npm/rules/<id>/<id>.mdc`).
|
|
68
|
-
|
|
69
|
-
Повертає `Promise<string>` — очікуваний (нормалізований) текст дзеркала після інлайнінгу шаблонів. Хоча сама функція не використовує `async`/`await`, її результат типізовано як `Promise`, оскільки делегує виклик до `inlineTemplateLinks`, яка є асинхронною (її результат може бути thenable). Це означає, що споживач має `await`-нути повернене значення.
|
|
70
|
-
|
|
71
|
-
Алгоритм:
|
|
72
|
-
|
|
73
|
-
1. Синхронно зчитує вміст канонічного файлу як UTF-8 (`readFileSync(canonicalPath, 'utf8')`).
|
|
74
|
-
2. Викликає `inlineTemplateLinks(content, dirname(canonicalPath))`, передаючи прочитаний текст та теку канону як base для розв'язання шляхів до шаблонів.
|
|
75
|
-
3. Повертає результат трансформації.
|
|
76
|
-
|
|
77
|
-
Side effects: одне читання з диску. Подальша поведінка щодо шаблонів інкапсульована в `inlineTemplateLinks` (див. її документацію). Контракт: цей же самий трансформ застосовує синк, тому очікуваний вміст детермінований по канону.
|
|
78
|
-
|
|
79
|
-
Помилки: якщо файл за `canonicalPath` не існує або недоступний — `readFileSync` кине помилку. Викличні сторони мають гарантувати існування (`listManagedMirrors` уже фільтрує неіснуючі канони).
|
|
80
|
-
|
|
81
|
-
### `findMirrorDrift(repoRoot)`
|
|
82
|
-
|
|
83
|
-
Сигнатура: `async function findMirrorDrift(repoRoot: string): Promise<string[]>`
|
|
84
|
-
|
|
85
|
-
Параметри:
|
|
86
|
-
|
|
87
|
-
- `repoRoot` — абсолютний шлях до кореня репозиторію.
|
|
88
|
-
|
|
89
|
-
Повертає `Promise<string[]>` — відсортований за зростанням масив `id` правил, де дзеркало розійшлося з очікуваним вмістом.
|
|
90
|
-
|
|
91
|
-
Алгоритм:
|
|
92
|
-
|
|
93
|
-
1. Заводить порожній масив `drift`.
|
|
94
|
-
2. Послідовно (через `for...of`) обходить усі керовані дзеркала, отримані з `listManagedMirrors(repoRoot)`.
|
|
95
|
-
3. Для кожного дзеркала `m`:
|
|
96
|
-
- `await`-ить очікуваний вміст через `expectedMirrorContent(m.canonicalPath)`;
|
|
97
|
-
- синхронно зчитує фактичний вміст файлу дзеркала `readFileSync(m.mirrorPath, 'utf8')`;
|
|
98
|
-
- якщо стрічки не дорівнюють — додає `m.id` до `drift`.
|
|
99
|
-
4. Повертає `drift.sort()` (лексикографічне сортування).
|
|
100
|
-
|
|
101
|
-
Side effects: тільки читання з диску. Не записує жодних файлів, не пише в лог.
|
|
102
|
-
|
|
103
|
-
Зауваження щодо порівняння: рівність стрічок є точною (строге `!==` по UTF-8 тексту). Будь-яка різниця в пробілах, символах кінця рядка чи порядку інлайнених шаблонів буде розцінена як дрейф.
|
|
104
|
-
|
|
105
|
-
## Залежності
|
|
106
|
-
|
|
107
|
-
Стандартна бібліотека Node.js:
|
|
108
|
-
|
|
109
|
-
- `node:fs` — `existsSync`, `readdirSync`, `readFileSync`. Усі виклики синхронні. Імпорт зроблено через `node:`-префікс для явної прив'язки до built-in модуля.
|
|
110
|
-
- `node:path` — `dirname`, `join`. Використовуються для безпечного складання абсолютних шляхів і отримання батьківської теки канону.
|
|
111
|
-
|
|
112
|
-
Локальні модулі:
|
|
113
|
-
|
|
114
|
-
- `./inline-template-links.mjs` — імпорт іменованої функції `inlineTemplateLinks(content, baseDir)`. Це той самий трансформ, що його використовує синк дзеркал; саме завдяки спільному використанню досягається консистентність між «гардом дрейфу» і «генератором дзеркал».
|
|
115
|
-
|
|
116
|
-
Зовнішніх npm-залежностей немає.
|
|
117
|
-
|
|
118
|
-
Константи на рівні модуля:
|
|
119
|
-
|
|
120
|
-
- `MIRROR_PREFIX = 'n-'` — префікс імені файлів дзеркал.
|
|
121
|
-
- `MDC_EXT = '.mdc'` — розширення файлів правил Cursor.
|
|
122
|
-
|
|
123
|
-
## Потік виконання / Використання
|
|
124
|
-
|
|
125
|
-
Типові сценарії використання модуля:
|
|
126
|
-
|
|
127
|
-
1. Тест-гард парності (CI). Споживач передає корінь репо й перевіряє, що дрейф порожній:
|
|
128
|
-
|
|
129
|
-
```js
|
|
130
|
-
import { findMirrorDrift } from './mirror-parity.mjs'
|
|
131
|
-
|
|
132
|
-
const drift = await findMirrorDrift(repoRoot)
|
|
133
|
-
if (drift.length) {
|
|
134
|
-
throw new Error(`Mirror drift detected for: ${drift.join(', ')}`)
|
|
135
|
-
}
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
2. Разова регенерація дзеркал. Споживач отримує список керованих дзеркал і для кожного перезаписує файл дзеркала очікуваним вмістом:
|
|
139
|
-
|
|
140
|
-
```js
|
|
141
|
-
import { writeFileSync } from 'node:fs'
|
|
142
|
-
import { listManagedMirrors, expectedMirrorContent } from './mirror-parity.mjs'
|
|
143
|
-
|
|
144
|
-
for (const m of listManagedMirrors(repoRoot)) {
|
|
145
|
-
const expected = await expectedMirrorContent(m.canonicalPath)
|
|
146
|
-
writeFileSync(m.mirrorPath, expected)
|
|
147
|
-
}
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
(Сам модуль `mirror-parity.mjs` записів не виконує — це задача викличного скрипта.)
|
|
151
|
-
|
|
152
|
-
Внутрішній потік виконання `findMirrorDrift`:
|
|
153
|
-
|
|
154
|
-
1. Виклик `listManagedMirrors(repoRoot)`:
|
|
155
|
-
- перевірка існування `.cursor/rules`;
|
|
156
|
-
- читання списку файлів;
|
|
157
|
-
- фільтрація за префіксом `n-` і розширенням `.mdc`;
|
|
158
|
-
- обчислення `id`, `mirrorPath`, `canonicalPath`;
|
|
159
|
-
- відкидання дзеркал без канону.
|
|
160
|
-
2. Послідовний обхід отриманих описів:
|
|
161
|
-
- читання канону → `inlineTemplateLinks` → очікуваний текст;
|
|
162
|
-
- читання дзеркала → порівняння;
|
|
163
|
-
- накопичення id з дрейфом.
|
|
164
|
-
3. Сортування результату та повернення.
|
|
165
|
-
|
|
166
|
-
Контрактна гарантія: якщо синк використовує ту ж саму функцію `inlineTemplateLinks` для генерації дзеркал, то регенерація закриває будь-який дрейф, виявлений `findMirrorDrift`. Якщо дрейф виявлено — він завжди вказує на людську помилку (зміна канону без регенерації) або на розбіжність версій трансформу.
|
|
167
|
-
|
|
168
|
-
Обмеження:
|
|
169
|
-
|
|
170
|
-
- Обхід послідовний (без `Promise.all`) — простіший контракт по помилках, але повільніший на великих наборах правил. Зважаючи на типову кількість правил у `.cursor/rules`, це не критично.
|
|
171
|
-
- Усі читання файлів синхронні, попри асинхронну сигнатуру `findMirrorDrift` — асинхронність зумовлена тільки інтерфейсом `inlineTemplateLinks`.
|
|
172
|
-
- Префікс `n-` зашитий константою — додавання інших префіксів дзеркал вимагатиме зміни модуля.
|
|
173
|
-
- Зовнішні дзеркала (без канону в `npm/rules/<id>/`) автоматично пропускаються; модуль не повідомляє про них окремо.
|
|
34
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
@@ -3,36 +3,33 @@ type: JS Module
|
|
|
3
3
|
title: rule-meta.mjs
|
|
4
4
|
resource: npm/scripts/lib/rule-meta.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 36aea8cb
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Парсер інтерпретує метадані правил, що знаходяться у `npm/rules/<id>/meta.json`. Він реалізує data-driven логіку для визначення умов активації кожного детектора. Специфікації активації (`auto`) нормалізуються на основі вмісту `meta.json`, підтримуючи чотири типи: константа `RULE_ALWAYS` ("завжди"), залежності від інших правил, шаблони за допомогою `glob`, або незводимі предикати. Парсер не виконує операцій запису у файлову систему чи бази даних і забезпечує безпечну роботу, перехоплюючи помилки.
|
|
10
14
|
|
|
11
15
|
## Поведінка
|
|
12
16
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
RULE_ALWAYS — константа, що позначає безумовну активацію правила.
|
|
18
|
+
parseRuleAutoSpec — Нормалізує значення поля `auto` з метаданих правила у дискриміновану специфікацію активації.
|
|
19
|
+
parseRuleLintSpec — Нормалізує значення поля `lint` з метаданих правила у специфікацію області застосування детектора.
|
|
20
|
+
readRuleMetaRaw — Читає та парсить вміст `main.json` з каталогу правила, повертаючи його як об'єкт або `null` у разі помилки чи відсутності файлу.
|
|
17
21
|
|
|
18
22
|
## Публічний API
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
+
RULE_ALWAYS — константа, що вказує на безумовну активацію.
|
|
25
|
+
parseRuleAutoSpec — перетворює налаштування автоматичного визначення правил з `meta.json` у структурований формат.
|
|
26
|
+
parseRuleLintSpec — перетворює налаштування лінтування з `meta.json` у визначення області дії детектора.
|
|
27
|
+
"per-file" — визначає, що детектор працює з окремими зміненими файлами (порівняння змін з оригіналом).
|
|
28
|
+
"full" — вказує на повний, нероздільний аналіз між усіма файлами (активується лише при використанні прапорця `--full` або в CI).
|
|
29
|
+
readRuleMetaRaw — зчитує та обробляє метадані одного правила з файлу `meta.json`.
|
|
24
30
|
|
|
25
31
|
## Гарантії поведінки
|
|
26
32
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- `parseRuleLintPhase` повертає `true` якщо правило успішно розібрано на етапі linting.
|
|
31
|
-
- `parseRuleLintPhase` повертає `false` якщо правило не може бути розібрано на етапі linting.
|
|
32
|
-
- `readRuleMetaRaw` повертає `true` якщо метадані правила успішно прочитані.
|
|
33
|
-
- `readRuleMetaRaw` повертає `false` якщо метадані правила не можуть бути прочитані.
|
|
34
|
-
- У разі невдачі, функція повертає `false` або `null`.
|
|
35
|
-
- Функції не кидають винятків.
|
|
36
|
-
- Немає кешування.
|
|
37
|
-
- Немає гарантій щодо стану файлів або каталогів.
|
|
38
|
-
- Поля `worktree` правила не використовуються.
|
|
33
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
34
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
35
|
+
- За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
|
|
@@ -3,27 +3,27 @@ type: JS Module
|
|
|
3
3
|
title: run-rule.mjs
|
|
4
4
|
resource: npm/scripts/lib/run-rule.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
|
|
6
|
+
crc: 7d0585e1
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 90
|
|
8
9
|
---
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Файл оркеструє виконання одного правила під CLI `fix`. Він послідовно застосовує гейт `applies` з `js/applies.mjs` для визначення придатності правила. Якщо гейт повертає `false`, правило не застосовується. Далі виконуються JS-концерни та Policy-концерни в алфавітному порядку. Резолвер `resolveTargetFiles` ділить кеш між концернами. Кожен concern створює власний репортер, а їхні exit-коди OR-уються в єдиний контракт, що забезпечує 0/1 результат для правила. Оркестратор спирається на конфігурації `target.json` та `.n-cursor.json`.
|
|
11
14
|
|
|
12
15
|
## Поведінка
|
|
13
16
|
|
|
14
|
-
runTemplateSubsetConcern
|
|
15
|
-
Перевіряє відповідність фактичного файлу канонічному шаблону.
|
|
17
|
+
runTemplateSubsetConcern виконує перевірку концерну, де канон визначається сніпетом у `target.json`, звіряючи його з актуальними файлами-таргетами.
|
|
16
18
|
|
|
17
|
-
runRule
|
|
18
|
-
Оркеструє виконання правила, включаючи перевірку гейту, JS-концернів та policy-концернів.
|
|
19
|
+
runRule оркеструє виконання одного правила, послідовно застосовуючи applies-гейт, виконуючи JS-концерни та запускаючи policy-концерни, а також перевіряючи відсутність markdown-посилань.
|
|
19
20
|
|
|
20
21
|
## Публічний API
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
runTemplateSubsetConcern — Порівнює фактичний файл із канонічним шаблоном (з `target.json`) для перевірки, чи всі обов'язкові елементи присутні, дозволяючи додаткові.
|
|
24
|
+
runRule — Виконує окреме правило, яке проходить через перевірки застосовності, JavaScript-концерни та політики.
|
|
24
25
|
|
|
25
26
|
## Гарантії поведінки
|
|
26
27
|
|
|
27
|
-
- Read-only:
|
|
28
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
28
29
|
- Кешує результати в межах одного прогону.
|
|
29
|
-
- Не звертається до мережі.
|
|
@@ -3,33 +3,31 @@ type: JS Module
|
|
|
3
3
|
title: skill-meta.mjs
|
|
4
4
|
resource: npm/scripts/lib/skill-meta.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: c0918db5
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Спільний парсер метаданих скіла, що зчитує дані з `npm/skills/<id>/meta.json`. Він є єдиним джерелом правди для конфігурації скілів, визначаючи умови автоактивації (через поле `auto`, де `SKILL_ALWAYS` означає "завжди"), чи виконувати скіл в окремому git-worktree (`worktree`), та чи вимагає скіл запуску з кореня репозиторію (`requireRoot`). Модуль надає механізми для парсингу цих метаданих, перевірки вимог до кореня та читання сирих даних. Він працює в режимі fail-safe, перехоплюючи помилки та повертаючи порожнє значення замість винятків.
|
|
10
14
|
|
|
11
15
|
## Поведінка
|
|
12
16
|
|
|
13
|
-
SKILL_ALWAYS
|
|
14
|
-
parseSkillAutoSpec
|
|
15
|
-
skillRequiresRoot
|
|
16
|
-
readSkillMetaRaw
|
|
17
|
+
SKILL_ALWAYS — надає літерал для безумовної автоактивації скіла.
|
|
18
|
+
parseSkillAutoSpec — перетворює значення поля `auto` з метаданих скіла у специфікацію автоактивації.
|
|
19
|
+
skillRequiresRoot — визначає, чи вимагає скіл запуску з кореня репозиторію, виходячи з метаданих.
|
|
20
|
+
readSkillMetaRaw — читає та парсить файл `main.json` у каталозі скіла, повертаючи його вміст або `null` у разі помилки.
|
|
17
21
|
|
|
18
22
|
## Публічний API
|
|
19
23
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
SKILL_ALWAYS — маркер, що вказує на безумовну активацію
|
|
25
|
+
parseSkillAutoSpec — витягує налаштування автоматичного запуску з `meta.json`
|
|
26
|
+
skillRequiresRoot — визначає, чи потрібен запуск скіла з кореня репозиторію
|
|
27
|
+
readSkillMetaRaw — зчитує та обробляє метадані окремого скіла з `meta.json`
|
|
24
28
|
|
|
25
29
|
## Гарантії поведінки
|
|
26
30
|
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- `worktree` має значення `true` лише для скілів, які потребують окремого git-worktree.
|
|
31
|
-
- `requireRoot` має значення `true` лише для скілів, які мутують в CWD без worktree-ізоляції.
|
|
32
|
-
- Якщо `worktree` має значення `true`, поле `requireRoot` не використовується.
|
|
33
|
-
- Не використовує кеш.
|
|
34
|
-
- Не кидає винятків.
|
|
35
|
-
- Гарантує, що `meta.json` є єдиним джерелом правди для скілу.
|
|
31
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
32
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
33
|
+
- За певних помилок повертає порожнє значення (напр. `null`) замість винятку.
|
|
@@ -3,24 +3,24 @@ type: JS Module
|
|
|
3
3
|
title: timing-summary.mjs
|
|
4
4
|
resource: npm/scripts/lib/timing-summary.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 47660e16
|
|
7
7
|
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
8
|
score: 100
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
## Огляд
|
|
12
12
|
|
|
13
|
-
Формує
|
|
13
|
+
Формує рядок, що відображає тривалість у форматі `<ціла>.<десята>s`, забезпечуючи стабільну одиницю вимірювання для всіх інтервалів. Генерує звіт про час виконання для orchestrator `fix` / `lint`, який включає деталі кожного вимірювання та загальний час. Звіт містить маркер `❌` на рядку, якщо відповідний вимірник не пройшов успішно. Дані для звітів отримуються з `package.json` та використовуються у точках виклику `runFixCommand` у `bin/n-cursor.js` та `runLintCli` у `scripts/lib/run-lint-cli.mjs`. Функція є чистою, не виконує I/O, і повертає готовий рядок з фінальним `\n`, друк якого здійснюється на стороні виклику.
|
|
14
14
|
|
|
15
15
|
## Поведінка
|
|
16
16
|
|
|
17
|
-
formatDurationMs
|
|
18
|
-
formatTimingSummary генерує багаторядковий
|
|
17
|
+
formatDurationMs форматує тривалість у мілісекундах як рядок у форматі `<ціла>.<десята>s`.
|
|
18
|
+
formatTimingSummary генерує багаторядковий текстовий звіт про час виконання, включаючи деталі кожного запису та загальний час.
|
|
19
19
|
|
|
20
20
|
## Публічний API
|
|
21
21
|
|
|
22
|
-
⏱ formatDurationMs: Перетворює мілісекунди
|
|
23
|
-
⏱ formatTimingSummary: Генерує багаторядковий вивід
|
|
22
|
+
⏱ formatDurationMs: Перетворює мілісекунди у формат `<sec>.<десята>s`, використовуючи округлення вниз.
|
|
23
|
+
⏱ formatTimingSummary: Генерує багаторядковий вивід таблиці-резюме часу виконання.
|
|
24
24
|
|
|
25
25
|
## Гарантії поведінки
|
|
26
26
|
|
|
@@ -30,7 +30,7 @@ export function listManagedMirrors(repoRoot) {
|
|
|
30
30
|
return {
|
|
31
31
|
id,
|
|
32
32
|
mirrorPath: join(rulesDir, f),
|
|
33
|
-
canonicalPath: join(repoRoot, 'npm/rules', id,
|
|
33
|
+
canonicalPath: join(repoRoot, 'npm/rules', id, `main${MDC_EXT}`)
|
|
34
34
|
}
|
|
35
35
|
})
|
|
36
36
|
.filter(m => existsSync(m.canonicalPath))
|
|
@@ -70,7 +70,7 @@ export function parseRuleLintSpec(value) {
|
|
|
70
70
|
* @returns {Record<string, unknown> | null} обʼєкт або `null` (немає файлу / невалідний JSON / не-обʼєкт)
|
|
71
71
|
*/
|
|
72
72
|
export function readRuleMetaRaw(ruleDir) {
|
|
73
|
-
const metaPath = join(ruleDir, '
|
|
73
|
+
const metaPath = join(ruleDir, 'main.json')
|
|
74
74
|
if (!existsSync(metaPath)) return null
|
|
75
75
|
try {
|
|
76
76
|
const parsed = JSON.parse(readFileSync(metaPath, 'utf8'))
|
package/scripts/lib/run-rule.mjs
CHANGED
|
@@ -81,7 +81,7 @@ export async function runTemplateSubsetConcern(concernAbsDir, target, files, rul
|
|
|
81
81
|
for (const file of files) {
|
|
82
82
|
const rel = relative(process.cwd(), file) || file
|
|
83
83
|
const actual = await parseByExt(file)
|
|
84
|
-
const opts = { targetPath: rel, source:
|
|
84
|
+
const opts = { targetPath: rel, source: 'main.mdc' }
|
|
85
85
|
const violations = [
|
|
86
86
|
...(typeof data.snippet === 'string'
|
|
87
87
|
? checkTextSubset(actual, data.snippet, opts)
|
|
@@ -118,7 +118,7 @@ async function runPolicyConcern(bundledRulesDir, ruleId, concernName, walkCache)
|
|
|
118
118
|
if (target.files.required && target.files.single) {
|
|
119
119
|
const msg =
|
|
120
120
|
target.missingMessage ??
|
|
121
|
-
`${target.files.single} не існує — створи згідно
|
|
121
|
+
`${target.files.single} не існує — створи згідно main.mdc (${ruleId}.${concernName})`
|
|
122
122
|
reporter.fail(msg)
|
|
123
123
|
}
|
|
124
124
|
return reporter.getExitCode()
|
|
@@ -182,11 +182,11 @@ export async function runRule(rule, bundledRulesDir, walkCache) {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
const ruleDir = join(bundledRulesDir, rule.id)
|
|
185
|
-
const missing = await findMissingMdcRefs(ruleDir
|
|
185
|
+
const missing = await findMissingMdcRefs(ruleDir)
|
|
186
186
|
if (missing.length > 0) {
|
|
187
187
|
const reporter = createCheckReporter()
|
|
188
188
|
for (const rel of missing) {
|
|
189
|
-
reporter.fail(
|
|
189
|
+
reporter.fail(`main.mdc: відсутнє markdown-посилання на template-файл ${rel}`)
|
|
190
190
|
}
|
|
191
191
|
if (reporter.getExitCode() !== 0) totalCode = 1
|
|
192
192
|
}
|
|
@@ -56,7 +56,7 @@ export function skillRequiresRoot(meta) {
|
|
|
56
56
|
* @returns {Record<string, unknown> | null} розпарсений обʼєкт або `null` (немає файлу / невалідний JSON / не-обʼєкт)
|
|
57
57
|
*/
|
|
58
58
|
export function readSkillMetaRaw(skillDir) {
|
|
59
|
-
const metaPath = join(skillDir, '
|
|
59
|
+
const metaPath = join(skillDir, 'main.json')
|
|
60
60
|
if (!existsSync(metaPath)) return null
|
|
61
61
|
try {
|
|
62
62
|
const parsed = JSON.parse(readFileSync(metaPath, 'utf8'))
|
|
@@ -6,18 +6,18 @@ resource: npm/scripts/utils/
|
|
|
6
6
|
|
|
7
7
|
# npm/scripts/utils
|
|
8
8
|
|
|
9
|
-
| Файл
|
|
10
|
-
|
|
11
|
-
| [ast-scan-utils.mjs](ast-scan-utils.md)
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
|---|---|
|
|
11
|
+
| [ast-scan-utils.mjs](ast-scan-utils.md) | JS Module |
|
|
12
12
|
| [ensure-gitignore-entries.mjs](ensure-gitignore-entries.md) | JS Module |
|
|
13
|
-
| [find-package-json-paths.mjs](find-package-json-paths.md)
|
|
14
|
-
| [lock-cache-dir.mjs](lock-cache-dir.md)
|
|
15
|
-
| [pass.mjs](pass.md)
|
|
16
|
-
| [resolve-cargo-manifest.mjs](resolve-cargo-manifest.md)
|
|
17
|
-
| [resolve-cmd.mjs](resolve-cmd.md)
|
|
18
|
-
| [resolve-js-root.mjs](resolve-js-root.md)
|
|
19
|
-
| [test-helpers.mjs](test-helpers.md)
|
|
20
|
-
| [walk-cache.mjs](walk-cache.md)
|
|
21
|
-
| [walkDir.mjs](walkDir.md)
|
|
22
|
-
| [with-lock.mjs](with-lock.md)
|
|
23
|
-
| [worktree-fingerprint.mjs](worktree-fingerprint.md)
|
|
13
|
+
| [find-package-json-paths.mjs](find-package-json-paths.md) | JS Module |
|
|
14
|
+
| [lock-cache-dir.mjs](lock-cache-dir.md) | JS Module |
|
|
15
|
+
| [pass.mjs](pass.md) | JS Module |
|
|
16
|
+
| [resolve-cargo-manifest.mjs](resolve-cargo-manifest.md) | JS Module |
|
|
17
|
+
| [resolve-cmd.mjs](resolve-cmd.md) | JS Module |
|
|
18
|
+
| [resolve-js-root.mjs](resolve-js-root.md) | JS Module |
|
|
19
|
+
| [test-helpers.mjs](test-helpers.md) | JS Module |
|
|
20
|
+
| [walk-cache.mjs](walk-cache.md) | JS Module |
|
|
21
|
+
| [walkDir.mjs](walkDir.md) | JS Module |
|
|
22
|
+
| [with-lock.mjs](with-lock.md) | JS Module |
|
|
23
|
+
| [worktree-fingerprint.mjs](worktree-fingerprint.md) | JS Module |
|
|
@@ -3,27 +3,26 @@ type: JS Module
|
|
|
3
3
|
title: resolve-js-root.mjs
|
|
4
4
|
resource: npm/scripts/utils/resolve-js-root.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
6
|
+
crc: 99e5a8a4
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 100
|
|
7
9
|
---
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
## Огляд
|
|
12
|
+
|
|
13
|
+
Визначає корінь JS-коду для проєктів, використовуючи `package.json` та `.n-cursor.json` як конфігураційні файли. Функція `resolveJsRoot` знаходить перший workspace (з підтримкою glob-патернів типу `cf/*`) для workspace-проєктів або корінь поточної директорії для single-package. Функція `resolveAllJsRoots` знаходить усі відповідні шляхи. Код свідомо ігнорує шляхи `.git` та `node_modules`. Ця утиліта є спільною для coverage-провайдера JS та test-концерну stryker_config (DRY).
|
|
10
14
|
|
|
11
15
|
## Поведінка
|
|
12
16
|
|
|
13
|
-
resolveJsRoot
|
|
14
|
-
resolveAllJsRoots
|
|
17
|
+
resolveJsRoot повертає абсолютний шлях до першого JS-кореня проєкту, якщо він існує, або null, якщо кореневий package.json відсутній.
|
|
18
|
+
resolveAllJsRoots повертає масив абсолютних шляхів до всіх JS-коренів проєкту, враховуючи визначення `workspaces` у кореневому package.json, ігноруючи каталоги `.git` та `node_modules`.
|
|
15
19
|
|
|
16
20
|
## Публічний API
|
|
17
21
|
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
resolveJsRoot — знаходить кореневий каталог JavaScript-проєкту.
|
|
23
|
+
resolveAllJsRoots — повертає шляхи до коренів усіх JavaScript-проєктів у робочому просторі.
|
|
20
24
|
|
|
21
25
|
## Гарантії поведінки
|
|
22
26
|
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- Повертає `null`, якщо не вдалося визначити кореневий JS-файл.
|
|
26
|
-
- Не обробляє помилки, а повертає `false` або `null`.
|
|
27
|
-
- Ігнорує директорії `.git` та `node_modules`.
|
|
28
|
-
- Не використовує кешування.
|
|
29
|
-
- Не здійснює мережевих запитів.
|
|
27
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
28
|
+
- Свідомо пропускає шляхи: `.git`, `node_modules`.
|