@nitra/cursor 1.4.1 → 1.5.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,34 +1,41 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { readFile } from 'node:fs/promises'
3
3
 
4
+ import { pass } from './utils/pass.mjs'
5
+
4
6
  /**
5
7
  * Перевіряє відповідність проєкту правилам js-lint.mdc
6
8
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
7
9
  */
8
10
  export async function check() {
9
11
  let exitCode = 0
10
- const pass = msg => console.log(` ✅ ${msg}`)
11
12
  const fail = msg => {
12
13
  console.log(` ❌ ${msg}`)
13
14
  exitCode = 1
14
15
  }
15
16
 
16
- existsSync('eslint.config.js')
17
- ? pass('eslint.config.js існує')
18
- : existsSync('eslint.config.mjs')
19
- ? pass('eslint.config.mjs існує')
20
- : fail('Відсутній eslint.config.js — створи його з getConfig від @nitra/eslint-config')
17
+ if (existsSync('eslint.config.js')) {
18
+ pass('eslint.config.js існує')
19
+ } else if (existsSync('eslint.config.mjs')) {
20
+ pass('eslint.config.mjs існує')
21
+ } else {
22
+ fail('Відсутній eslint.config.js — створи його з getConfig від @nitra/eslint-config')
23
+ }
21
24
 
22
25
  if (existsSync('package.json')) {
23
26
  const pkg = JSON.parse(await readFile('package.json', 'utf8'))
24
27
 
25
- pkg.scripts?.['lint-js']
26
- ? pass('package.json містить скрипт lint-js')
27
- : fail('package.json не містить скрипт "lint-js" — додай: "oxlint --fix && bunx eslint --fix ."')
28
+ if (pkg.scripts?.['lint-js']) {
29
+ pass('package.json містить скрипт lint-js')
30
+ } else {
31
+ fail('package.json не містить скрипт "lint-js" — додай: "oxlint --fix && bunx eslint --fix ."')
32
+ }
28
33
 
29
- pkg.devDependencies?.['@nitra/eslint-config']
30
- ? pass('@nitra/eslint-config є в devDependencies')
31
- : fail('@nitra/eslint-config відсутній в devDependencies — додай: bun add -d @nitra/eslint-config')
34
+ if (pkg.devDependencies?.['@nitra/eslint-config']) {
35
+ pass('@nitra/eslint-config є в devDependencies')
36
+ } else {
37
+ fail('@nitra/eslint-config відсутній в devDependencies — додай: bun add -d @nitra/eslint-config')
38
+ }
32
39
 
33
40
  const nodeEngine = pkg.engines?.node
34
41
  if (nodeEngine) {
@@ -46,8 +53,16 @@ export async function check() {
46
53
  if (existsSync('.github/workflows/lint-js.yml')) {
47
54
  const content = await readFile('.github/workflows/lint-js.yml', 'utf8')
48
55
  pass('lint-js.yml існує')
49
- content.includes('oxlint') ? pass('lint-js.yml містить oxlint') : fail('lint-js.yml не містить oxlint')
50
- content.includes('eslint') ? pass('lint-js.yml містить eslint') : fail('lint-js.yml не містить eslint')
56
+ if (content.includes('oxlint')) {
57
+ pass('lint-js.yml містить oxlint')
58
+ } else {
59
+ fail('lint-js.yml не містить oxlint')
60
+ }
61
+ if (content.includes('eslint')) {
62
+ pass('lint-js.yml містить eslint')
63
+ } else {
64
+ fail('lint-js.yml не містить eslint')
65
+ }
51
66
  } else {
52
67
  fail('.github/workflows/lint-js.yml не існує — створи його')
53
68
  }
@@ -1,13 +1,14 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { readFile } from 'node:fs/promises'
3
3
 
4
+ import { pass } from './utils/pass.mjs'
5
+
4
6
  /**
5
7
  * Перевіряє відповідність проєкту правилам js-pino.mdc
6
8
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
7
9
  */
8
10
  export async function check() {
9
11
  let exitCode = 0
10
- const pass = msg => console.log(` ✅ ${msg}`)
11
12
  const fail = msg => {
12
13
  console.log(` ❌ ${msg}`)
13
14
  exitCode = 1
@@ -1,13 +1,14 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { readFile } from 'node:fs/promises'
3
3
 
4
+ import { pass } from './utils/pass.mjs'
5
+
4
6
  /**
5
7
  * Перевіряє відповідність проєкту правилам nginx-default-tpl.mdc
6
8
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
7
9
  */
8
10
  export async function check() {
9
11
  let exitCode = 0
10
- const pass = msg => console.log(` ✅ ${msg}`)
11
12
  const fail = msg => {
12
13
  console.log(` ❌ ${msg}`)
13
14
  exitCode = 1
@@ -24,17 +25,23 @@ export async function check() {
24
25
  pass(`${found} існує`)
25
26
  const content = await readFile(found, 'utf8')
26
27
 
27
- content.includes('listen 8080')
28
- ? pass('Nginx слухає порт 8080')
29
- : fail(`${found}: має містити listen 8080`)
28
+ if (content.includes('listen 8080')) {
29
+ pass('Nginx слухає порт 8080')
30
+ } else {
31
+ fail(`${found}: має містити listen 8080`)
32
+ }
30
33
 
31
- content.includes('/healthz')
32
- ? pass('Є location /healthz')
33
- : fail(`${found}: відсутній location /healthz`)
34
+ if (content.includes('/healthz')) {
35
+ pass('Є location /healthz')
36
+ } else {
37
+ fail(`${found}: відсутній location /healthz`)
38
+ }
34
39
 
35
- content.includes('gzip_static on')
36
- ? pass('gzip_static увімкнено')
37
- : fail(`${found}: має містити gzip_static on`)
40
+ if (content.includes('gzip_static on')) {
41
+ pass('gzip_static увімкнено')
42
+ } else {
43
+ fail(`${found}: має містити gzip_static on`)
44
+ }
38
45
 
39
46
  if (content.includes('proxy_pass')) {
40
47
  fail(`${found} містить proxy_pass — перенеси проксі-логіку до HTTPRoute в k8s`)
@@ -43,16 +50,20 @@ export async function check() {
43
50
 
44
51
  if (existsSync('.vscode/extensions.json')) {
45
52
  const ext = JSON.parse(await readFile('.vscode/extensions.json', 'utf8'))
46
- ext.recommendations?.includes('ahmadalli.vscode-nginx-conf')
47
- ? pass('extensions.json містить ahmadalli.vscode-nginx-conf')
48
- : fail('extensions.json не містить ahmadalli.vscode-nginx-conf')
53
+ if (ext.recommendations?.includes('ahmadalli.vscode-nginx-conf')) {
54
+ pass('extensions.json містить ahmadalli.vscode-nginx-conf')
55
+ } else {
56
+ fail('extensions.json не містить ahmadalli.vscode-nginx-conf')
57
+ }
49
58
  }
50
59
 
51
60
  if (existsSync('.vscode/settings.json')) {
52
61
  const s = JSON.parse(await readFile('.vscode/settings.json', 'utf8'))
53
- s['[nginx]']?.['editor.defaultFormatter'] === 'ahmadalli.vscode-nginx-conf'
54
- ? pass('settings.json: nginx formatter налаштовано')
55
- : fail('settings.json: [nginx] defaultFormatter має бути ahmadalli.vscode-nginx-conf')
62
+ if (s['[nginx]']?.['editor.defaultFormatter'] === 'ahmadalli.vscode-nginx-conf') {
63
+ pass('settings.json: nginx formatter налаштовано')
64
+ } else {
65
+ fail('settings.json: [nginx] defaultFormatter має бути ahmadalli.vscode-nginx-conf')
66
+ }
56
67
  }
57
68
 
58
69
  return exitCode
@@ -1,23 +1,32 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { readFile, stat } from 'node:fs/promises'
3
3
 
4
+ import { pass } from './utils/pass.mjs'
5
+
4
6
  /**
5
7
  * Перевіряє відповідність проєкту правилам npm-module.mdc
6
8
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
7
9
  */
8
10
  export async function check() {
9
11
  let exitCode = 0
10
- const pass = msg => console.log(` ✅ ${msg}`)
11
12
  const fail = msg => {
12
13
  console.log(` ❌ ${msg}`)
13
14
  exitCode = 1
14
15
  }
15
16
 
16
- existsSync('package.json') ? pass('package.json існує') : fail('package.json не існує')
17
+ if (existsSync('package.json')) {
18
+ pass('package.json існує')
19
+ } else {
20
+ fail('package.json не існує')
21
+ }
17
22
 
18
23
  if (existsSync('npm')) {
19
24
  const s = await stat('npm')
20
- s.isDirectory() ? pass('npm/ директорія існує') : fail('npm має бути директорією')
25
+ if (s.isDirectory()) {
26
+ pass('npm/ директорія існує')
27
+ } else {
28
+ fail('npm має бути директорією')
29
+ }
21
30
  } else {
22
31
  fail('npm/ директорія не існує')
23
32
  }
@@ -32,13 +41,17 @@ export async function check() {
32
41
  }
33
42
  }
34
43
 
35
- existsSync('npm/package.json')
36
- ? pass('npm/package.json існує')
37
- : fail('npm/package.json не існує — створи package.json для npm модуля')
44
+ if (existsSync('npm/package.json')) {
45
+ pass('npm/package.json існує')
46
+ } else {
47
+ fail('npm/package.json не існує — створи package.json для npm модуля')
48
+ }
38
49
 
39
- existsSync('.github/workflows')
40
- ? pass('.github/workflows/ існує')
41
- : fail('.github/workflows/ не існує')
50
+ if (existsSync('.github/workflows')) {
51
+ pass('.github/workflows/ існує')
52
+ } else {
53
+ fail('.github/workflows/ не існує')
54
+ }
42
55
 
43
56
  return exitCode
44
57
  }
@@ -1,13 +1,14 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { readFile } from 'node:fs/promises'
3
3
 
4
+ import { pass } from './utils/pass.mjs'
5
+
4
6
  /**
5
7
  * Перевіряє відповідність проєкту правилам style-lint.mdc
6
8
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
7
9
  */
8
10
  export async function check() {
9
11
  let exitCode = 0
10
- const pass = msg => console.log(` ✅ ${msg}`)
11
12
  const fail = msg => {
12
13
  console.log(` ❌ ${msg}`)
13
14
  exitCode = 1
@@ -16,13 +17,17 @@ export async function check() {
16
17
  if (existsSync('package.json')) {
17
18
  const pkg = JSON.parse(await readFile('package.json', 'utf8'))
18
19
 
19
- pkg.scripts?.['lint-style']
20
- ? pass('package.json містить скрипт lint-style')
21
- : fail('package.json не містить скрипт "lint-style"')
20
+ if (pkg.scripts?.['lint-style']) {
21
+ pass('package.json містить скрипт lint-style')
22
+ } else {
23
+ fail('package.json не містить скрипт "lint-style"')
24
+ }
22
25
 
23
- pkg.devDependencies?.['@nitra/stylelint-config']
24
- ? pass('@nitra/stylelint-config є в devDependencies')
25
- : fail('@nitra/stylelint-config відсутній — bun add -d @nitra/stylelint-config')
26
+ if (pkg.devDependencies?.['@nitra/stylelint-config']) {
27
+ pass('@nitra/stylelint-config є в devDependencies')
28
+ } else {
29
+ fail('@nitra/stylelint-config відсутній — bun add -d @nitra/stylelint-config')
30
+ }
26
31
 
27
32
  const stylelintCfg = pkg.stylelint
28
33
  if (stylelintCfg?.extends === '@nitra/stylelint-config') {
@@ -34,33 +39,47 @@ export async function check() {
34
39
  }
35
40
  }
36
41
 
37
- existsSync('.stylelintignore')
38
- ? pass('.stylelintignore існує')
39
- : fail('.stylelintignore не існує — створи з вмістом: dist/')
42
+ if (existsSync('.stylelintignore')) {
43
+ pass('.stylelintignore існує')
44
+ } else {
45
+ fail('.stylelintignore не існує — створи з вмістом: dist/')
46
+ }
40
47
 
41
48
  if (existsSync('.github/workflows/lint-style.yml')) {
42
49
  const content = await readFile('.github/workflows/lint-style.yml', 'utf8')
43
50
  pass('lint-style.yml існує')
44
- content.includes('stylelint')
45
- ? pass('lint-style.yml містить stylelint')
46
- : fail('lint-style.yml не містить виклик stylelint')
51
+ if (content.includes('stylelint')) {
52
+ pass('lint-style.yml містить stylelint')
53
+ } else {
54
+ fail('lint-style.yml не містить виклик stylelint')
55
+ }
47
56
  } else {
48
57
  fail('.github/workflows/lint-style.yml не існує — створи його')
49
58
  }
50
59
 
51
60
  if (existsSync('.vscode/extensions.json')) {
52
61
  const ext = JSON.parse(await readFile('.vscode/extensions.json', 'utf8'))
53
- ext.recommendations?.includes('stylelint.vscode-stylelint')
54
- ? pass('extensions.json містить stylelint.vscode-stylelint')
55
- : fail('extensions.json не містить stylelint.vscode-stylelint')
62
+ if (ext.recommendations?.includes('stylelint.vscode-stylelint')) {
63
+ pass('extensions.json містить stylelint.vscode-stylelint')
64
+ } else {
65
+ fail('extensions.json не містить stylelint.vscode-stylelint')
66
+ }
56
67
  } else {
57
68
  fail('.vscode/extensions.json не існує')
58
69
  }
59
70
 
60
71
  if (existsSync('.vscode/settings.json')) {
61
72
  const s = JSON.parse(await readFile('.vscode/settings.json', 'utf8'))
62
- s['css.validate'] === false ? pass('css.validate вимкнено') : fail('settings.json: css.validate має бути false')
63
- s['scss.validate'] === false ? pass('scss.validate вимкнено') : fail('settings.json: scss.validate має бути false')
73
+ if (s['css.validate'] === false) {
74
+ pass('css.validate вимкнено')
75
+ } else {
76
+ fail('settings.json: css.validate має бути false')
77
+ }
78
+ if (s['scss.validate'] === false) {
79
+ pass('scss.validate вимкнено')
80
+ } else {
81
+ fail('settings.json: scss.validate має бути false')
82
+ }
64
83
  }
65
84
 
66
85
  return exitCode
@@ -0,0 +1,139 @@
1
+ import { existsSync } from 'node:fs'
2
+ import { readFile } from 'node:fs/promises'
3
+
4
+ import { pass } from './utils/pass.mjs'
5
+
6
+ /**
7
+ * Перевіряє відповідність проєкту правилам text.mdc (cspell, markdownlint-cli2, v8r)
8
+ * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
9
+ */
10
+ export async function check() {
11
+ let exitCode = 0
12
+ const fail = msg => {
13
+ console.log(` ❌ ${msg}`)
14
+ exitCode = 1
15
+ }
16
+
17
+ if (existsSync('.vscode/extensions.json')) {
18
+ try {
19
+ const ext = JSON.parse(await readFile('.vscode/extensions.json', 'utf8'))
20
+ const rec = ext.recommendations
21
+ if (Array.isArray(rec) && rec.includes('DavidAnson.vscode-markdownlint')) {
22
+ pass('extensions.json містить DavidAnson.vscode-markdownlint')
23
+ } else {
24
+ fail('extensions.json: додай "DavidAnson.vscode-markdownlint" у recommendations (див. n-text.mdc)')
25
+ }
26
+ } catch {
27
+ fail('.vscode/extensions.json — невалідний JSON')
28
+ }
29
+ } else {
30
+ fail('.vscode/extensions.json не існує — створи з recommendations згідно n-text.mdc')
31
+ }
32
+
33
+ if (existsSync('.markdownlint-cli2.jsonc')) {
34
+ try {
35
+ const ml = JSON.parse(await readFile('.markdownlint-cli2.jsonc', 'utf8'))
36
+ pass('.markdownlint-cli2.jsonc існує і є валідним JSON')
37
+ if (ml.gitignore === true) {
38
+ pass('.markdownlint-cli2.jsonc: gitignore увімкнено')
39
+ } else {
40
+ fail('.markdownlint-cli2.jsonc: додай на верхньому рівні "gitignore": true (див. n-text.mdc)')
41
+ }
42
+ } catch {
43
+ fail('.markdownlint-cli2.jsonc — невалідний JSON; перевір синтаксис')
44
+ }
45
+ } else {
46
+ fail('.markdownlint-cli2.jsonc не існує — створи згідно n-text.mdc')
47
+ }
48
+
49
+ if (existsSync('.cspell.json')) {
50
+ const cfg = JSON.parse(await readFile('.cspell.json', 'utf8'))
51
+
52
+ if (cfg.version === '0.2') {
53
+ pass('.cspell.json version: 0.2')
54
+ } else {
55
+ fail('.cspell.json version має бути "0.2"')
56
+ }
57
+
58
+ if (cfg.language) {
59
+ pass(`.cspell.json language: "${cfg.language}"`)
60
+ } else {
61
+ fail('.cspell.json не містить поле language')
62
+ }
63
+
64
+ const imports = cfg.import || []
65
+ if (imports.some(i => i.includes('@nitra/cspell-dict'))) {
66
+ pass('.cspell.json імпортує @nitra/cspell-dict')
67
+ } else {
68
+ fail('.cspell.json не імпортує @nitra/cspell-dict/cspell-ext.json')
69
+ }
70
+
71
+ if (Array.isArray(cfg.ignorePaths)) {
72
+ pass('.cspell.json містить ignorePaths')
73
+ } else {
74
+ fail('.cspell.json не містить ignorePaths')
75
+ }
76
+ } else {
77
+ fail('.cspell.json не існує — створи його')
78
+ }
79
+
80
+ if (existsSync('package.json')) {
81
+ const pkg = JSON.parse(await readFile('package.json', 'utf8'))
82
+ const devDeps = pkg.devDependencies || {}
83
+
84
+ if (devDeps['@nitra/cspell-dict']) {
85
+ pass('@nitra/cspell-dict є в devDependencies')
86
+ } else {
87
+ fail('@nitra/cspell-dict відсутній — bun add -d @nitra/cspell-dict')
88
+ }
89
+
90
+ if (devDeps['markdownlint-cli2']) {
91
+ pass('markdownlint-cli2 є в devDependencies')
92
+ } else {
93
+ fail('markdownlint-cli2 відсутній — bun add -d markdownlint-cli2')
94
+ }
95
+
96
+ const lintText = pkg.scripts?.['lint-text']
97
+ const v8rCalls = typeof lintText === 'string' ? (lintText.match(/bunx v8r/g) || []).length : 0
98
+ const eq98Hints = typeof lintText === 'string' ? (lintText.match(/eq 98/g) || []).length : 0
99
+ if (
100
+ typeof lintText === 'string' &&
101
+ lintText.includes('cspell') &&
102
+ lintText.includes('markdownlint-cli2') &&
103
+ lintText.includes('**/*.mdc') &&
104
+ v8rCalls >= 4 &&
105
+ eq98Hints >= 4 &&
106
+ lintText.includes('**/*.json') &&
107
+ lintText.includes('**/*.yml') &&
108
+ lintText.includes('**/*.yaml') &&
109
+ lintText.includes('**/*.toml')
110
+ ) {
111
+ pass('package.json: lint-text — чотири виклики v8r з || [ $? -eq 98 ] для json/yml/yaml/toml')
112
+ } else {
113
+ fail(
114
+ 'package.json: lint-text — чотири (bunx v8r "<glob>" || [ $? -eq 98 ]) для **/*.json **/*.yml **/*.yaml **/*.toml (див. n-text.mdc)'
115
+ )
116
+ }
117
+
118
+ if (existsSync('.github/workflows/lint-text.yml')) {
119
+ const wf = await readFile('.github/workflows/lint-text.yml', 'utf8')
120
+ if (wf.includes('bun run lint-text')) {
121
+ pass('lint-text.yml викликає bun run lint-text')
122
+ } else {
123
+ fail('lint-text.yml має містити крок bun run lint-text')
124
+ }
125
+ } else {
126
+ fail('.github/workflows/lint-text.yml не існує — створи згідно n-text.mdc')
127
+ }
128
+
129
+ if (existsSync('.cspell.json')) {
130
+ const cfg = JSON.parse(await readFile('.cspell.json', 'utf8'))
131
+ const hasUkImport = (cfg.import || []).some(i => i.includes('@cspell/dict-uk-ua'))
132
+ if (hasUkImport && !devDeps['@cspell/dict-uk-ua']) {
133
+ fail('.cspell.json імпортує @cspell/dict-uk-ua, але пакет відсутній в devDependencies')
134
+ }
135
+ }
136
+ }
137
+
138
+ return exitCode
139
+ }
@@ -1,13 +1,14 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { readFile } from 'node:fs/promises'
3
3
 
4
+ import { pass } from './utils/pass.mjs'
5
+
4
6
  /**
5
7
  * Перевіряє відповідність проєкту правилам vue.mdc
6
8
  * @returns {Promise<number>} 0 — все OK, 1 — є проблеми
7
9
  */
8
10
  export async function check() {
9
11
  let exitCode = 0
10
- const pass = msg => console.log(` ✅ ${msg}`)
11
12
  const fail = msg => {
12
13
  console.log(` ❌ ${msg}`)
13
14
  exitCode = 1
@@ -15,9 +16,11 @@ export async function check() {
15
16
 
16
17
  if (existsSync('.vscode/extensions.json')) {
17
18
  const ext = JSON.parse(await readFile('.vscode/extensions.json', 'utf8'))
18
- ext.recommendations?.includes('Vue.volar')
19
- ? pass('extensions.json містить Vue.volar')
20
- : fail('extensions.json не містить Vue.volar — додай до recommendations')
19
+ if (ext.recommendations?.includes('Vue.volar')) {
20
+ pass('extensions.json містить Vue.volar')
21
+ } else {
22
+ fail('extensions.json не містить Vue.volar — додай до recommendations')
23
+ }
21
24
  } else {
22
25
  fail('.vscode/extensions.json не існує')
23
26
  }
@@ -28,7 +31,11 @@ export async function check() {
28
31
  const devDeps = pkg.devDependencies || {}
29
32
  const allDeps = { ...deps, ...devDeps }
30
33
 
31
- deps.vue ? pass(`vue в dependencies: ${deps.vue}`) : fail('vue відсутній в dependencies')
34
+ if (deps.vue) {
35
+ pass(`vue в dependencies: ${deps.vue}`)
36
+ } else {
37
+ fail('vue відсутній в dependencies')
38
+ }
32
39
 
33
40
  if (devDeps.vite) {
34
41
  const match = devDeps.vite.match(/(\d+)/)
@@ -41,29 +48,45 @@ export async function check() {
41
48
  fail('vite відсутній в devDependencies')
42
49
  }
43
50
 
44
- devDeps['@vitejs/plugin-vue']
45
- ? pass(`@vitejs/plugin-vue: ${devDeps['@vitejs/plugin-vue']}`)
46
- : fail('@vitejs/plugin-vue відсутній в devDependencies')
51
+ if (devDeps['@vitejs/plugin-vue']) {
52
+ pass(`@vitejs/plugin-vue: ${devDeps['@vitejs/plugin-vue']}`)
53
+ } else {
54
+ fail('@vitejs/plugin-vue відсутній в devDependencies')
55
+ }
47
56
 
48
- allDeps['vue-macros']
49
- ? pass(`vue-macros: ${allDeps['vue-macros']}`)
50
- : fail('vue-macros відсутній — bun add -d vue-macros')
57
+ if (allDeps['vue-macros']) {
58
+ pass(`vue-macros: ${allDeps['vue-macros']}`)
59
+ } else {
60
+ fail('vue-macros відсутній — bun add -d vue-macros')
61
+ }
51
62
 
52
- allDeps['unplugin-auto-import']
53
- ? pass('unplugin-auto-import присутній')
54
- : fail('unplugin-auto-import відсутній — bun add -d unplugin-auto-import')
63
+ if (allDeps['unplugin-auto-import']) {
64
+ pass('unplugin-auto-import присутній')
65
+ } else {
66
+ fail('unplugin-auto-import відсутній — bun add -d unplugin-auto-import')
67
+ }
55
68
 
56
- allDeps['vite-plugin-vue-layouts-next']
57
- ? pass('vite-plugin-vue-layouts-next присутній')
58
- : fail('vite-plugin-vue-layouts-next відсутній — bun add -d vite-plugin-vue-layouts-next')
69
+ if (allDeps['vite-plugin-vue-layouts-next']) {
70
+ pass('vite-plugin-vue-layouts-next присутній')
71
+ } else {
72
+ fail('vite-plugin-vue-layouts-next відсутній — bun add -d vite-plugin-vue-layouts-next')
73
+ }
59
74
  }
60
75
 
61
76
  const configFiles = ['vite.config.js', 'vite.config.ts', 'vite.config.mjs']
62
77
  const viteConfig = configFiles.find(f => existsSync(f))
63
78
  if (viteConfig) {
64
79
  const content = await readFile(viteConfig, 'utf8')
65
- content.includes('VueMacros') ? pass('vite.config використовує VueMacros') : fail(`${viteConfig} не містить VueMacros`)
66
- content.includes('AutoImport') ? pass('vite.config використовує AutoImport') : fail(`${viteConfig} не містить AutoImport`)
80
+ if (content.includes('VueMacros')) {
81
+ pass('vite.config використовує VueMacros')
82
+ } else {
83
+ fail(`${viteConfig} не містить VueMacros`)
84
+ }
85
+ if (content.includes('AutoImport')) {
86
+ pass('vite.config використовує AutoImport')
87
+ } else {
88
+ fail(`${viteConfig} не містить AutoImport`)
89
+ }
67
90
  } else {
68
91
  fail('vite.config.js не існує')
69
92
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Логує успішний результат перевірки (рядок з галочкою)
3
+ * @param {string} msg текст повідомлення
4
+ */
5
+ export function pass(msg) {
6
+ console.log(` ✅ ${msg}`)
7
+ }
@@ -1,10 +1,10 @@
1
1
  ---
2
- name: n-fix-cursor
2
+ name: n-fix
3
3
  description: >-
4
4
  Виправити проєкт відповідно до всіх правил в .cursor/rules/
5
5
  ---
6
6
 
7
- # Fix Cursor — автоматичне виправлення проєкту
7
+ # n-fix — автоматичне виправлення проєкту
8
8
 
9
9
  ## Workflow
10
10
 
@@ -40,9 +40,14 @@ oxfmt .
40
40
 
41
41
  ```bash
42
42
  bun run lint-js
43
+ bun run lint-text
43
44
  bun run lint-style
44
45
  ```
45
46
 
47
+ На помилках: auto-fix (якщо є), інакше правки в коді/конфігах; повторюй доки скрипт завершується з `0`.
48
+
49
+ Підсумок: Перелічи запущені скрипти та зміни; опиши блокери, якщо лишились.
50
+
46
51
  7. **Верифікація** — перевір що все виправлено:
47
52
 
48
53
  ```bash
@@ -47,11 +47,12 @@ Telegram підтримує моноширний шрифт через markdown-
47
47
  <1-2 речення — що отримали, яка вигода>
48
48
  ```
49
49
 
50
- #тег використовуються наступні:
51
- якщо публікація стосовно AI, то #ai
52
- якщо публікація стосовно npm модуля, то #npm
53
- якщо публікація стосовно розробки, то #dev
54
- якщо публікація стосовно інфраструктури, скриптів, налаштувань, ефективності коду чи безпеки то #sre
50
+ Теги (хештеги в кінці поста) — підбір за темою:
51
+
52
+ - якщо публікація стосовно AI, то `#ai`
53
+ - якщо публікація стосовно npm модуля, то `#npm`
54
+ - якщо публікація стосовно розробки, то `#dev`
55
+ - якщо публікація стосовно інфраструктури, скриптів, налаштувань, ефективності коду чи безпеки, то `#sre`
55
56
 
56
57
  ## Правила
57
58
 
@@ -68,6 +69,8 @@ Telegram підтримує моноширний шрифт через markdown-
68
69
 
69
70
  ````
70
71
  ```
72
+ #dev
73
+
71
74
  📌 Міграція з Prettier на oxfmt
72
75
 
73
76
  Проблема:
@@ -87,7 +90,5 @@ Prettier повільно форматував великі файли і
87
90
  Результат:
88
91
  Форматування працює миттєво при збереженні,
89
92
  зникли конфлікти між форматером і лінтером.
90
-
91
- #dx #tooling #oxfmt
92
93
  ```
93
94
  ````