@nitra/cursor 1.8.108 → 1.8.109
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/mdc/bun.mdc +8 -1
- package/mdc/js-lint.mdc +4 -1
- package/package.json +1 -1
- package/scripts/check-bun.mjs +29 -2
- package/scripts/check-js-lint.mjs +28 -1
package/mdc/bun.mdc
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Bun як єдиний package manager у монорепо
|
|
3
3
|
alwaysApply: true
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.7'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
Проект використовує тільки Bun для керування залежностями та запуску скриптів.
|
|
@@ -44,6 +44,13 @@ Lockfile у репозиторії: `bun.lock`.
|
|
|
44
44
|
Не створювати `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`.
|
|
45
45
|
Видалити якщо вони є. Видалити .yarn та .yarnrc.yml якщо вони є.
|
|
46
46
|
|
|
47
|
+
У корені репозиторію має бути **`bunfig.toml`** з **hoisted** лінкером (пласке `node_modules`, сумісне з інструментами, які не розуміють ізольований layout Bun):
|
|
48
|
+
|
|
49
|
+
```toml title="bunfig.toml"
|
|
50
|
+
[install]
|
|
51
|
+
linker = "hoisted"
|
|
52
|
+
```
|
|
53
|
+
|
|
47
54
|
Для Bun monorepo:
|
|
48
55
|
|
|
49
56
|
- Встановлювати залежності у відповідному пакеті, а не в корені без потреби.
|
package/mdc/js-lint.mdc
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
description: Перевірка JavaScript коду
|
|
3
3
|
alwaysApply: true
|
|
4
|
-
version: '1.
|
|
4
|
+
version: '1.14'
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
**oxlint**, **ESLint**, **jscpd**. У скрипті **`lint-js`** і в CI — **`bunx oxlint`**, **`bunx eslint`**, **`bunx jscpd`** (у CI без **`--fix`** для oxlint/eslint — див. приклад workflow нижче). Без **prettier** і **@nitra/prettier-config**. У **`devDependencies`** має бути **`@nitra/eslint-config` мінімум `^3.5.0`** (з ним транзитивно йде **`@e18e/eslint-plugin`** для oxlint); пакет **`@e18e/eslint-plugin`** окремо не додавай. Пакети oxlint/eslint/jscpd не додавай без потреби монорепо.
|
|
@@ -16,8 +16,11 @@ version: '1.13'
|
|
|
16
16
|
}
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
У кожному **`package.json`** проєкту (корінь і всі workspace-пакети) має бути **`"type": "module"`** — весь код у ESM.
|
|
20
|
+
|
|
19
21
|
```json title="package.json"
|
|
20
22
|
{
|
|
23
|
+
"type": "module",
|
|
21
24
|
"scripts": {
|
|
22
25
|
"lint-js": "bunx oxlint --fix && bunx eslint --fix . && bunx jscpd ."
|
|
23
26
|
},
|
package/package.json
CHANGED
package/scripts/check-bun.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Перевіряє відповідність репозиторію правилам Bun (bun.mdc).
|
|
3
3
|
*
|
|
4
|
-
* Очікує наявність `bun.lock`,
|
|
5
|
-
* і поле `packageManager`
|
|
4
|
+
* Очікує наявність `bun.lock`, `bunfig.toml` з `linker = "hoisted"` у секції `[install]`,
|
|
5
|
+
* забороняє lockfile та артефакти yarn/pnpm, директорію `.yarn` і поле `packageManager`
|
|
6
|
+
* у кореневому `package.json`.
|
|
6
7
|
*
|
|
7
8
|
* У кореневому `package.json` не має бути поля **`dependencies`**; у **`devDependencies`** дозволені лише
|
|
8
9
|
* пакети **`@nitra/*`** (наприклад **`@nitra/cspell-dict`**, **`@nitra/eslint-config`**).
|
|
@@ -20,6 +21,30 @@ import { readFile } from 'node:fs/promises'
|
|
|
20
21
|
import { createCheckReporter } from './utils/check-reporter.mjs'
|
|
21
22
|
|
|
22
23
|
const OXFMT_END_RE = /&&[ \t]+oxfmt[ \t]+\.[ \t]*$/
|
|
24
|
+
const HOISTED_LINKER_RE = /^\s*linker\s*=\s*"hoisted"\s*$/m
|
|
25
|
+
const INSTALL_SECTION_RE = /^\s*\[install\]\s*$/m
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Перевіряє `bunfig.toml` на секцію `[install]` з `linker = "hoisted"`.
|
|
29
|
+
* @param {{ pass: (msg: string) => void, fail: (msg: string) => void }} reporter репортер
|
|
30
|
+
*/
|
|
31
|
+
async function checkBunfigHoisted(reporter) {
|
|
32
|
+
const { pass, fail } = reporter
|
|
33
|
+
if (!existsSync('bunfig.toml')) {
|
|
34
|
+
fail('Відсутній bunfig.toml — створи з [install] linker = "hoisted" (bun.mdc)')
|
|
35
|
+
return
|
|
36
|
+
}
|
|
37
|
+
const content = await readFile('bunfig.toml', 'utf8')
|
|
38
|
+
if (!INSTALL_SECTION_RE.test(content)) {
|
|
39
|
+
fail('bunfig.toml: відсутня секція [install] (bun.mdc)')
|
|
40
|
+
return
|
|
41
|
+
}
|
|
42
|
+
if (HOISTED_LINKER_RE.test(content)) {
|
|
43
|
+
pass('bunfig.toml: [install] linker = "hoisted"')
|
|
44
|
+
} else {
|
|
45
|
+
fail('bunfig.toml: у секції [install] має бути linker = "hoisted" (bun.mdc)')
|
|
46
|
+
}
|
|
47
|
+
}
|
|
23
48
|
|
|
24
49
|
/**
|
|
25
50
|
* Чи ім'я пакета дозволене в кореневих `devDependencies` за bun.mdc (лише **`@nitra/*`**).
|
|
@@ -162,6 +187,8 @@ export async function check() {
|
|
|
162
187
|
fail('Відсутній bun.lock — запусти bun i')
|
|
163
188
|
}
|
|
164
189
|
|
|
190
|
+
await checkBunfigHoisted(reporter)
|
|
191
|
+
|
|
165
192
|
const cursorRules = await loadNCursorRules()
|
|
166
193
|
|
|
167
194
|
if (!existsSync('package.json')) {
|
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
* `.oxlintrc.json` з `jsPlugins` (`@e18e/eslint-plugin`) і правилом `e18e/prefer-includes: error`,
|
|
6
6
|
* `@nitra/eslint-config` у devDependencies мінімум **3.5.0** (транзитивний `@e18e/eslint-plugin` для oxlint), `.jscpd.json`
|
|
7
7
|
* (gitignore, exitCode, reporters, minLines), workflow `lint-js.yml` (checkout@v6, setup-bun-deps,
|
|
8
|
-
* bunx без --fix), без prettier, `engines.node` >= 24
|
|
8
|
+
* bunx без --fix), без prettier, `engines.node` >= 24, `"type": "module"` у кореневому
|
|
9
|
+
* і всіх workspace `package.json`. Дубль перевірки JS у `lint.yml` — заборонено.
|
|
9
10
|
*/
|
|
10
11
|
import { existsSync } from 'node:fs'
|
|
11
12
|
import { readFile } from 'node:fs/promises'
|
|
@@ -167,6 +168,21 @@ function checkPackageJsonLintDeps(pkg, passFn, failFn) {
|
|
|
167
168
|
}
|
|
168
169
|
}
|
|
169
170
|
|
|
171
|
+
/**
|
|
172
|
+
* Перевіряє, що package.json має `"type": "module"`.
|
|
173
|
+
* @param {string} label шлях або назва пакета для повідомлень
|
|
174
|
+
* @param {{ type?: string }} pkg parsed package.json
|
|
175
|
+
* @param {(msg: string) => void} passFn callback при успішній перевірці
|
|
176
|
+
* @param {(msg: string) => void} failFn callback при помилці
|
|
177
|
+
*/
|
|
178
|
+
function checkPackageJsonTypeModule(label, pkg, passFn, failFn) {
|
|
179
|
+
if (pkg.type === 'module') {
|
|
180
|
+
passFn(`${label}: "type": "module"`)
|
|
181
|
+
} else {
|
|
182
|
+
failFn(`${label}: має містити "type": "module" (js-lint.mdc)`)
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
170
186
|
/**
|
|
171
187
|
* Перевіряє package.json на lint-js, prettier, eslint-config, engines.node.
|
|
172
188
|
* @param {(msg: string) => void} passFn callback при успішній перевірці
|
|
@@ -176,6 +192,17 @@ async function checkPackageJsonJsLint(passFn, failFn) {
|
|
|
176
192
|
if (!existsSync('package.json')) return
|
|
177
193
|
const pkg = JSON.parse(await readFile('package.json', 'utf8'))
|
|
178
194
|
|
|
195
|
+
checkPackageJsonTypeModule('package.json', pkg, passFn, failFn)
|
|
196
|
+
|
|
197
|
+
const workspaces = Array.isArray(pkg.workspaces) ? pkg.workspaces : []
|
|
198
|
+
for (const ws of workspaces) {
|
|
199
|
+
const wsPkgPath = `${ws}/package.json`
|
|
200
|
+
if (existsSync(wsPkgPath)) {
|
|
201
|
+
const wsPkg = JSON.parse(await readFile(wsPkgPath, 'utf8'))
|
|
202
|
+
checkPackageJsonTypeModule(wsPkgPath, wsPkg, passFn, failFn)
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
179
206
|
const lintJs = pkg.scripts?.['lint-js']
|
|
180
207
|
if (lintJs) {
|
|
181
208
|
passFn('package.json містить скрипт lint-js')
|