@7n/rules-lang-js 0.7.0 → 0.7.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.1] - 2026-07-20
4
+
5
+ ### Fixed
6
+
7
+ - style/lint: stylelint — задекларована залежність плагіна (раніше резолвилась лише транзитивно у цьому монорепо через @nitra/stylelint-config); відсутність тула тепер дає видимий warn-diagnostic замість мовчазного no-op (незалежний консюмер бачив би 'зелений' style-лінт, який насправді нічого не перевіряв)
8
+
3
9
  ## [0.7.0] - 2026-07-19
4
10
 
5
11
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@7n/rules-lang-js",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "Плагін @7n/rules: JS/npm/bun-екосистема — lint-правила (js/bun/vue/js-run/npm-module/db), taze-провайдер (package.json, bunx taze) і doc-files-екстрактори (oxc AST)",
5
5
  "keywords": [
6
6
  "javascript",
@@ -58,7 +58,8 @@
58
58
  "jscpd": "^5.0.11",
59
59
  "knip": "^6.22.0",
60
60
  "oxc-parser": "^0.137.0",
61
- "oxlint": "^1.68.0"
61
+ "oxlint": "^1.68.0",
62
+ "stylelint": "^17.6.0"
62
63
  },
63
64
  "peerDependencies": {
64
65
  "@7n/rules": ">=1.27.0"
@@ -122,7 +122,7 @@ export function findRedisImportsInText(
122
122
 
123
123
  ### Внутрішні (репозиторій)
124
124
 
125
- Імпорт із `'../../../scripts/utils/ast-scan-utils.mjs'` — спільні утиліти AST-сканера для всіх правил у `npm/rules/*/lib/`:
125
+ Імпорт із `'@7n/rules/scripts/utils/ast-scan-utils.mjs'` (ядро) — спільні утиліти AST-сканера, які використовують правила з декількох плагінів:
126
126
 
127
127
  - `dynamicImportModule(node)` — якщо вузол AST є динамічним `import('mod')`, повертає рядок `'mod'`, інакше `null`/`undefined`.
128
128
  - `langFromPath(path)` — обчислює `lang` для `oxc-parser` за розширенням шляху.
@@ -198,7 +198,7 @@ import x from 'my-redis-helpers' // довільний сторонній пак
198
198
  Контрольний перелік, за яким можна **відтворити** функціонал модуля «з нуля»:
199
199
 
200
200
  1. Створити файл `redis-imports.mjs`, що імпортує `parseSync` з `oxc-parser`.
201
- 2. Імпортувати з `'../../../scripts/utils/ast-scan-utils.mjs'` шість утиліт: `dynamicImportModule`, `langFromPath`, `normalizeSnippet`, `offsetToLine`, `requireCallModule`, `walkAstWithAncestors`.
201
+ 2. Імпортувати з `'@7n/rules/scripts/utils/ast-scan-utils.mjs'` шість утиліт: `dynamicImportModule`, `langFromPath`, `normalizeSnippet`, `offsetToLine`, `requireCallModule`, `walkAstWithAncestors`.
202
202
  3. Оголосити константу `SOURCE_FILE_RE = /\.([cm]?[jt]sx?)$/u`.
203
203
  4. Оголосити константу `FORBIDDEN_MODULE_NAMES` як `Set` із елементами: `'ioredis'`, `'node-redis'`, `'redis'`, `'@redis/client'`, `'@redis/json'`, `'@redis/search'`, `'@redis/time-series'`, `'@redis/bloom'`.
204
204
  5. Реалізувати приватну функцію `isForbiddenRedisModule(mod)`: повертає `true`, якщо `FORBIDDEN_MODULE_NAMES.has(mod)` **або** `mod.startsWith('ioredis/')` **або** `mod.startsWith('redis/')` **або** `mod.startsWith('@redis/')`.
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: plugins/lang-js/rules/style/admin_table/main.mjs
5
5
  docgen:
6
- crc: 267496d1
6
+ crc: fb8f81a5
7
7
  ---
8
8
 
9
9
  ## Огляд
@@ -13,8 +13,8 @@ const DEFINITION_RE = /\.n-admin-table\b/u
13
13
  * клас `n-admin-table`, він має бути визначений хоч в одному `.scss`/`.css`/`.vue`
14
14
  * (guide: `admin_table.mdc`). Для усунення false positives — крос-файлова перевірка,
15
15
  * тож потребує whole-repo сканування незалежно від `ctx.files`.
16
- * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
17
- * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
16
+ * @param {import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
17
+ * @returns {Promise<import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
18
18
  */
19
19
  export async function lint(ctx) {
20
20
  const reporter = createViolationReporter(ctx)
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: plugins/lang-js/rules/style/gap/main.mjs
5
5
  docgen:
6
- crc: 23cd7951
6
+ crc: 5d9d76e7
7
7
  ---
8
8
 
9
9
  ## Огляд
@@ -13,8 +13,8 @@ const DEFINITION_RE = /\.n-gap-(xs|sm|md|lg)\b/gu
13
13
  * використаний у `.vue`, має бути визначений хоч в одному `.scss`/`.css`/`.vue`
14
14
  * (guide: `gap.mdc`). Крос-файлова перевірка usage↔definition — потребує whole-repo
15
15
  * сканування незалежно від `ctx.files`.
16
- * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
17
- * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
16
+ * @param {import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
17
+ * @returns {Promise<import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
18
18
  */
19
19
  export async function lint(ctx) {
20
20
  const reporter = createViolationReporter(ctx)
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: fix-lint.mjs
4
4
  resource: plugins/lang-js/rules/style/lint/fix-lint.mjs
5
5
  docgen:
6
- crc: a63dc24c
6
+ crc: a44c6b01
7
7
  ---
8
8
 
9
9
  ## Огляд
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: plugins/lang-js/rules/style/lint/main.mjs
5
5
  docgen:
6
- crc: c9a94f80
6
+ crc: 25130f97
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  issues: judge:inaccurate:0.99
@@ -40,7 +40,7 @@ async function listStyleFiles(cwd, ctxFiles) {
40
40
  return (r.stdout ?? '').split('\0').filter(Boolean)
41
41
  }
42
42
 
43
- /** @type {import('../../../scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
43
+ /** @type {import('@7n/rules/scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
44
44
  export const patterns = [
45
45
  {
46
46
  id: 'style-stylelint-fix',
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * lint-поверхня style: read-only detector (stylelint без --fix) для css/scss/vue.
3
- * Per-file (ctx.files) або весь проєкт (ctx.files === undefined). Якщо stylelint
4
- * недоступний крок пропускається (без npx-автовстановлення).
3
+ * Per-file (ctx.files) або весь проєкт (ctx.files === undefined). `stylelint`
4
+ * задекларована залежність плагіна (справжній `npm install` завжди його ставить);
5
+ * якщо резолв все ж не вдався (побитий install, hoisting-аномалія) — крок
6
+ * пропускається з видимим warn-diagnostic, а не мовчки (без npx-автовстановлення).
5
7
  */
6
8
  import { existsSync } from 'node:fs'
7
9
  import { join } from 'node:path'
@@ -33,8 +35,8 @@ export function resolveStylelint(cwd) {
33
35
 
34
36
  /**
35
37
  * Detector style/lint (read-only).
36
- * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd, files)
37
- * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
38
+ * @param {import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd, files)
39
+ * @returns {Promise<import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
38
40
  */
39
41
  export async function lint(ctx) {
40
42
  const reporter = createViolationReporter(ctx)
@@ -54,8 +56,18 @@ export async function lint(ctx) {
54
56
 
55
57
  const stylelint = resolveStylelint(cwd)
56
58
  if (!stylelint) {
57
- // stylelint недоступний крок пропущено (без автовстановлення)
58
- return reporter.result()
59
+ // stylelint задекларована залежність плагіна, тож відсутність тут аномальна
60
+ // (побитий install, hoisting) — крок пропущено з видимим warn, не мовчки.
61
+ const result = reporter.result()
62
+ result.diagnostics = [
63
+ {
64
+ level: 'warn',
65
+ message:
66
+ 'lint-style: `stylelint` не резолвиться (ні node_modules/.bin, ні PATH) — CSS/SCSS/Vue-стилі НЕ перевірені ' +
67
+ 'цим прогоном (style.mdc). `stylelint` — залежність @7n/rules-lang-js; переустанови плагін, якщо бачиш це.'
68
+ }
69
+ ]
70
+ return result
59
71
  }
60
72
 
61
73
  const r = await spawnAsync(stylelint, targets, { cwd, shell: false })
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: plugins/lang-js/rules/style/quasar_fixes/main.mjs
5
5
  docgen:
6
- crc: 0f9c4631
6
+ crc: dec47808
7
7
  ---
8
8
 
9
9
  ## Огляд
@@ -21,8 +21,8 @@ const FIXES = [
21
21
  * `<q-scroll-area>` або `<q-tooltip>`, у `.scss`/`.css`/`.vue` має бути відповідний
22
22
  * CSS-фікс (guide: `quasar_fixes.mdc`). Крос-файлова перевірка usage↔definition —
23
23
  * потребує whole-repo сканування незалежно від `ctx.files`.
24
- * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
25
- * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
24
+ * @param {import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd)
25
+ * @returns {Promise<import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
26
26
  */
27
27
  export async function lint(ctx) {
28
28
  const reporter = createViolationReporter(ctx)
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: fix-tooling.mjs
4
4
  resource: plugins/lang-js/rules/style/tooling/fix-tooling.mjs
5
5
  docgen:
6
- crc: a25e47d2
6
+ crc: 033af5f9
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 100
9
9
  issues: judge:inaccurate:0.98
@@ -3,7 +3,7 @@ type: JS Module
3
3
  title: main.mjs
4
4
  resource: plugins/lang-js/rules/style/tooling/main.mjs
5
5
  docgen:
6
- crc: c96a4b01
6
+ crc: aeb36134
7
7
  model: omlx/gemma-4-e4b-it-OptiQ-4bit
8
8
  score: 90
9
9
  issues: anchor-miss:extensions.json,anchor-miss:settings.json,judge:inaccurate:0.99
@@ -12,7 +12,7 @@ const STYLELINTIGNORE_MISSING_RE = /\.stylelintignore не існує/u
12
12
  const STYLELINTIGNORE_NO_DIST_RE = /\.stylelintignore не містить рядка dist\//u
13
13
  const NO_STYLELINT_CONFIG_RE = /Немає конфігу stylelint/u
14
14
 
15
- /** @type {import('../../../scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
15
+ /** @type {import('@7n/rules/scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
16
16
  export const patterns = [
17
17
  {
18
18
  id: 'style-stylelintignore-create',
@@ -45,8 +45,8 @@ async function checkStylelintConfigPresence(reporter, cwd) {
45
45
 
46
46
  /**
47
47
  * Перевіряє відповідність проєкту правилам style.mdc
48
- * @param {import('../../../scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd тощо)
49
- * @returns {Promise<import('../../../scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
48
+ * @param {import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintContext} ctx контекст lint-прогону (cwd тощо)
49
+ * @returns {Promise<import('@7n/rules/scripts/lib/lint-surface/types.mjs').LintResult>} результат зі зібраними violations
50
50
  */
51
51
  export async function lint(ctx) {
52
52
  const cwd = ctx.cwd