@7n/rules 1.8.1 → 1.8.2
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,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.8.2] - 2026-07-17
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- bun/licensee: розрізняти crash інструмента (stderr) від реального ліцензійного порушення (stdout, --errors-only)
|
|
8
|
+
- k8s/manifests: знизити когнітивну складність ensureHasuraConfigMapRequiredEnv нижче порогу sonarjs
|
|
9
|
+
|
|
3
10
|
## [1.8.1] - 2026-07-17
|
|
4
11
|
|
|
5
12
|
### Changed
|
package/package.json
CHANGED
|
@@ -3,35 +3,28 @@ type: JS Module
|
|
|
3
3
|
title: main.mjs
|
|
4
4
|
resource: npm/rules/bun/licensee/main.mjs
|
|
5
5
|
docgen:
|
|
6
|
-
crc:
|
|
7
|
-
model:
|
|
8
|
-
score: 90
|
|
9
|
-
issues: surzhik,judge:inaccurate:0.96
|
|
10
|
-
judgeModel: openai-codex/gpt-5.4-mini
|
|
6
|
+
crc: 48c72e2b
|
|
7
|
+
model: manual
|
|
11
8
|
---
|
|
12
9
|
|
|
13
10
|
## Огляд
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
Read-only detector `bun/licensee`: перевіряє ліцензії npm-залежностей проєкту через зовнішній інструмент `licensee` (`bun x licensee`), звіряючи їх з allowlist у `.licensee.json`. Розрізняє два принципово різні провали: `licensee` знайшов реально заборонену ліцензію (`license-violation`) — і `licensee` сам впав з помилкою (`licensee-crashed`), наприклад через несумісність `@npmcli/arborist` (яким він читає `node_modules`) з деревом, зібраним `bun install`.
|
|
16
13
|
|
|
17
14
|
## Поведінка
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
3. Визначається команда `bun`. Якщо `bun` не знайдена у системному шляху, повідомляється про це (bun.mdc).
|
|
26
|
-
4. Виконується команда `bun x licensee --production --quiet` у корені проєкту.
|
|
27
|
-
5. Якщо команда `licensee` завершується успішно (статус 0), повідомляється, що ліцензії відповідають вимогам.
|
|
28
|
-
6. Якщо команда `licensee` завершується з помилкою (не 0), повідомляється про порушення ліцензій (код) (bun.mdc).
|
|
16
|
+
1. Якщо `.licensee.json` відсутній — `licensee-config-missing`; генерація конфігу — окремий T0-фікс (`fix-licensee.mjs`), не тут.
|
|
17
|
+
2. Якщо `bun` не знайдено в PATH — `bun-missing`.
|
|
18
|
+
3. Запускає `bun x licensee --production --errors-only` (без `--quiet` — реальне порушення потребує деталі: ім'я/версія/ліцензія пакета, які `licensee` пише в stdout через `print()`).
|
|
19
|
+
4. Статус 0 — без порушень.
|
|
20
|
+
5. Статус ≠ 0 і є вивід у **stderr** — трактується як crash/`die()` самого `licensee` (invalid config або необроблений виняток усередині тула), НЕ як ліцензійне порушення: `licensee-crashed`, повідомлення включає stderr і підказку перевірити вручну `bunx licensee --production`.
|
|
21
|
+
6. Статус ≠ 0 і stderr порожній, є вивід у **stdout** — це справжній `NOT APPROVED`-звіт від `licensee` (`--errors-only` друкує лише невідповідні пакети): `license-violation` з деталлю пакета/ліцензії у повідомленні.
|
|
29
22
|
|
|
30
23
|
## Публічний API
|
|
31
24
|
|
|
32
|
-
lint —
|
|
33
|
-
licensee — перевіряє відповідність ліцензій усіх використаних npm-залежностей файлу `.licensee.json`.
|
|
25
|
+
- `lint(ctx)` — detector-контракт unified lint surface; повертає `{ violations }`.
|
|
34
26
|
|
|
35
27
|
## Гарантії поведінки
|
|
36
28
|
|
|
37
|
-
- (
|
|
29
|
+
- Read-only: не пише `.licensee.json` і не змінює `node_modules`/lockfile сам (побічний ефект `bun x` — авто-встановлення пакета `licensee`, якщо відсутній у bunx-кеші, — керується bun, не цим модулем).
|
|
30
|
+
- Канал stdout/stderr — єдиний сигнал розрізнення crash vs реальне порушення; текстові евристики за вмістом повідомлення не використовуються.
|
|
@@ -34,11 +34,27 @@ export function lint(ctx) {
|
|
|
34
34
|
return reporter.result()
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
// Без --quiet: `licensee` пише реальні NOT APPROVED записи (name/version/license) у
|
|
38
|
+
// stdout через print() — деталь замість голого "код 1". Crash/die() усередині
|
|
39
|
+
// самого тула (invalid config, внутрішній виняток на кшталт "Cannot read properties
|
|
40
|
+
// of undefined (reading 'localeCompare')" — спостережено з @npmcli/arborist на
|
|
41
|
+
// bun-based node_modules) завжди йде у stderr через die(); легітимний звіт про
|
|
42
|
+
// порушення — лише у stdout. Канал розрізняє crash від реального порушення.
|
|
43
|
+
const r = spawnSync(bun, ['x', 'licensee', '--production', '--errors-only'], { cwd, encoding: 'utf8', shell: false })
|
|
38
44
|
if (r.status !== 0) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
const stderr = (r.stderr ?? '').trim().slice(0, 2000)
|
|
46
|
+
if (stderr) {
|
|
47
|
+
fail(
|
|
48
|
+
`lint-bun: licensee — інструмент завершився з помилкою, це НЕ підтверджене ліцензійне порушення ` +
|
|
49
|
+
`(код ${r.status}, bun.mdc). Ймовірна причина — несумісність @npmcli/arborist (яким licensee читає ` +
|
|
50
|
+
`node_modules) з деревом, зібраним bun install. Перевір вручну: \`bunx licensee --production\`.\n${stderr}`,
|
|
51
|
+
'licensee-crashed'
|
|
52
|
+
)
|
|
53
|
+
} else {
|
|
54
|
+
const stdout = (r.stdout ?? '').trim().slice(0, 2000)
|
|
55
|
+
const detail = stdout ? `\n${stdout}` : ''
|
|
56
|
+
fail(`lint-bun: licensee — порушення ліцензій (код ${r.status}, bun.mdc)${detail}`, 'license-violation')
|
|
57
|
+
}
|
|
42
58
|
}
|
|
43
59
|
return reporter.result()
|
|
44
60
|
}
|
|
@@ -157,6 +157,22 @@ function isFalsyBool(v) {
|
|
|
157
157
|
return typeof v === 'string' && v.trim().toLowerCase() === 'false'
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
/**
|
|
161
|
+
* Визначає значення для одного `HASURA_GRAPHQL_*` ключа за очікуванням із
|
|
162
|
+
* `HASURA_REQUIRED_ENV_VALUES`: `null` — довільне значення, проставляється лише
|
|
163
|
+
* якщо ключ відсутній (дефолт `'true'`); `'true'`/`'false'` — булеве порівняння
|
|
164
|
+
* (case-insensitive, `isTruthyBool`/`isFalsyBool`); інакше — точний рядок.
|
|
165
|
+
* @param {string|null} expected очікуване значення з `HASURA_REQUIRED_ENV_VALUES`
|
|
166
|
+
* @param {unknown} current поточне значення ключа в `data` (може бути `undefined`)
|
|
167
|
+
* @returns {string|null} значення для `setIn`, або `null`, якщо змін не потрібно
|
|
168
|
+
*/
|
|
169
|
+
function resolveHasuraEnvValue(expected, current) {
|
|
170
|
+
if (expected === null) return current === undefined ? 'true' : null
|
|
171
|
+
if (expected === 'true') return isTruthyBool(current) ? null : 'true'
|
|
172
|
+
if (expected === 'false') return isFalsyBool(current) ? null : 'false'
|
|
173
|
+
return current === expected ? null : expected
|
|
174
|
+
}
|
|
175
|
+
|
|
160
176
|
/**
|
|
161
177
|
* Проставляє обов'язкові `HASURA_GRAPHQL_*` env-ключі (`HASURA_REQUIRED_ENV_VALUES`,
|
|
162
178
|
* дзеркалить `k8s.hasura_configmap.rego`) у `data` документа `kind: ConfigMap`. Ключ з
|
|
@@ -177,32 +193,10 @@ export function ensureHasuraConfigMapRequiredEnv(content) {
|
|
|
177
193
|
|
|
178
194
|
let changed = false
|
|
179
195
|
for (const [key, expected] of Object.entries(HASURA_REQUIRED_ENV_VALUES)) {
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
changed = true
|
|
185
|
-
}
|
|
186
|
-
continue
|
|
187
|
-
}
|
|
188
|
-
if (expected === 'true') {
|
|
189
|
-
if (!isTruthyBool(current)) {
|
|
190
|
-
doc.setIn(['data', key], 'true')
|
|
191
|
-
changed = true
|
|
192
|
-
}
|
|
193
|
-
continue
|
|
194
|
-
}
|
|
195
|
-
if (expected === 'false') {
|
|
196
|
-
if (!isFalsyBool(current)) {
|
|
197
|
-
doc.setIn(['data', key], 'false')
|
|
198
|
-
changed = true
|
|
199
|
-
}
|
|
200
|
-
continue
|
|
201
|
-
}
|
|
202
|
-
if (current !== expected) {
|
|
203
|
-
doc.setIn(['data', key], expected)
|
|
204
|
-
changed = true
|
|
205
|
-
}
|
|
196
|
+
const value = resolveHasuraEnvValue(expected, doc.getIn(['data', key]))
|
|
197
|
+
if (value === null) continue
|
|
198
|
+
doc.setIn(['data', key], value)
|
|
199
|
+
changed = true
|
|
206
200
|
}
|
|
207
201
|
if (!changed) return null
|
|
208
202
|
return doc.toString()
|