fg-devkit 1.7.3 → 1.7.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/README.md
CHANGED
|
@@ -45,6 +45,24 @@ pnpm exec fgd typecheck
|
|
|
45
45
|
pnpm exec fgd typecheck-watch
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
## Bundled Fallow (dead code analysis)
|
|
49
|
+
|
|
50
|
+
`fg-devkit` also ships Fallow for dead code analysis in consuming repos.
|
|
51
|
+
|
|
52
|
+
Run dead code analysis via CLI:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pnpm exec fgd dead-code
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Or run Fallow directly with custom args:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pnpm exec fgd fallow dead-code --json
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
When you run `fgd sync-tooling-configs` (or `fgd sync-project-configs`), fg-devkit also writes a shared `.fallowrc.json` to the consuming repo.
|
|
65
|
+
|
|
48
66
|
To remove redundant tooling dependencies from a consuming repo:
|
|
49
67
|
|
|
50
68
|
```bash
|
|
@@ -136,6 +154,33 @@ export default {
|
|
|
136
154
|
...basePrettierConfig,
|
|
137
155
|
}
|
|
138
156
|
```
|
|
157
|
+
|
|
158
|
+
## Local development with pnpm link
|
|
159
|
+
|
|
160
|
+
Use this flow to test local `fg-devkit` changes in a consuming repo.
|
|
161
|
+
|
|
162
|
+
In this repo (`fg-devkit`):
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
pnpm install
|
|
166
|
+
pnpm link --global
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
In the consuming repo:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
pnpm link --global fg-devkit
|
|
173
|
+
pnpm install
|
|
174
|
+
pnpm exec fgd --help
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
To remove the global link in a consuming repo:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
pnpm unlink fg-devkit
|
|
181
|
+
pnpm install
|
|
182
|
+
```
|
|
183
|
+
|
|
139
184
|
## Install CLI in this repo
|
|
140
185
|
|
|
141
186
|
1) Add this to your shell config (`~/.zshrc`) and update `FGD_DEVKIT_PATH`:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/fallow-rs/fallow/main/schema.json",
|
|
3
|
+
"ignorePatterns": [
|
|
4
|
+
"**/*.d.ts",
|
|
5
|
+
"**/*.generated.*",
|
|
6
|
+
"dist/**",
|
|
7
|
+
"build/**",
|
|
8
|
+
"coverage/**",
|
|
9
|
+
"src/style.css",
|
|
10
|
+
"index.html"
|
|
11
|
+
],
|
|
12
|
+
"publicPackages": ["fds-vue-core"]
|
|
13
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fg-devkit",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.4",
|
|
4
4
|
"description": "Shared configs, scripts, and DX tooling for Vue / TypeScript frontend repos",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -72,6 +72,8 @@
|
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
|
+
"@inquirer/confirm": "^6.0.12",
|
|
76
|
+
"@inquirer/select": "^5.1.4",
|
|
75
77
|
"@intlify/eslint-plugin-vue-i18n": "4.3.0",
|
|
76
78
|
"@typescript-eslint/eslint-plugin": "8.58.2",
|
|
77
79
|
"@typescript-eslint/parser": "8.58.2",
|
|
@@ -83,6 +85,7 @@
|
|
|
83
85
|
"eslint": "10.2.1",
|
|
84
86
|
"eslint-plugin-prettier": "5.5.5",
|
|
85
87
|
"eslint-plugin-vue": "10.8.0",
|
|
88
|
+
"fallow": "^2.52.2",
|
|
86
89
|
"lefthook": "2.1.6",
|
|
87
90
|
"npm-check-updates": "21.0.3",
|
|
88
91
|
"prettier": "3.8.3",
|
package/scripts/fg-devkit.mjs
CHANGED
|
@@ -28,6 +28,8 @@
|
|
|
28
28
|
* pnpm exec fg-devkit format-check [prettier-args...] (same as format plus --check)
|
|
29
29
|
* pnpm exec fg-devkit typecheck [vue-tsc-args...] (run vue-tsc with fg-devkit bundled package)
|
|
30
30
|
* pnpm exec fg-devkit typecheck-watch [vue-tsc-args...] (same as typecheck plus --watch)
|
|
31
|
+
* pnpm exec fg-devkit fallow [fallow-args...] (run Fallow with fg-devkit bundled package)
|
|
32
|
+
* pnpm exec fg-devkit dead-code [fallow-args...] (same as: fallow dead-code [args...])
|
|
31
33
|
* pnpm exec fg-devkit poeditor-download [args...] (download translations using poeditor/.poeditor.json + env token)
|
|
32
34
|
* pnpm exec fg-devkit poeditor-upload [args...] (upload translations using poeditor/.poeditor.json + env token)
|
|
33
35
|
* Interactive menu (no subcommand):
|
|
@@ -405,6 +407,37 @@ function runBundledTypeScript(args = []) {
|
|
|
405
407
|
return r.status ?? 1
|
|
406
408
|
}
|
|
407
409
|
|
|
410
|
+
/** Run Fallow from fg-devkit's bundled dependency set. */
|
|
411
|
+
function runBundledFallow(args = []) {
|
|
412
|
+
let fallowBin
|
|
413
|
+
try {
|
|
414
|
+
const fallowPkgJson = require.resolve('fallow/package.json', {
|
|
415
|
+
paths: [fgRoot, process.cwd()],
|
|
416
|
+
})
|
|
417
|
+
const fallowPkgRoot = path.dirname(fallowPkgJson)
|
|
418
|
+
fallowBin = path.join(fallowPkgRoot, 'bin', 'fallow')
|
|
419
|
+
if (!fs.existsSync(fallowBin)) {
|
|
420
|
+
throw new Error('fallow bin not found')
|
|
421
|
+
}
|
|
422
|
+
} catch {
|
|
423
|
+
console.error('[fg-devkit] Could not resolve bundled fallow.')
|
|
424
|
+
console.error('[fg-devkit] Run pnpm install in fg-devkit and in the linked consumer, then retry.')
|
|
425
|
+
return 1
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
const r = spawnSync(process.execPath, [fallowBin, ...args], {
|
|
429
|
+
stdio: 'inherit',
|
|
430
|
+
cwd: process.cwd(),
|
|
431
|
+
env: process.env,
|
|
432
|
+
})
|
|
433
|
+
if (r.error) {
|
|
434
|
+
console.error('[fg-devkit] Could not run bundled fallow.')
|
|
435
|
+
console.error('[fg-devkit]', r.error.message)
|
|
436
|
+
return 1
|
|
437
|
+
}
|
|
438
|
+
return r.status ?? 1
|
|
439
|
+
}
|
|
440
|
+
|
|
408
441
|
/** Map subcommand name → script file (extra argv after subcommand is forwarded). */
|
|
409
442
|
const DIRECT_COMMANDS = {
|
|
410
443
|
'check-deps': 'check-dependency-policy.mjs',
|
|
@@ -461,6 +494,8 @@ Commands:
|
|
|
461
494
|
format-check [prettier-args...] Run Prettier with --check using fg-devkit bundled package
|
|
462
495
|
typecheck [vue-tsc-args...] Run vue-tsc using fg-devkit bundled package
|
|
463
496
|
typecheck-watch [vue-tsc-args...] Run vue-tsc with --watch using fg-devkit bundled package
|
|
497
|
+
fallow [fallow-args...] Run Fallow using fg-devkit bundled package
|
|
498
|
+
dead-code [fallow-args...] Run Fallow dead code analysis (shortcut for: fallow dead-code)
|
|
464
499
|
poeditor-download [args...] Download locale files via PoEditor (reads poeditor/.poeditor.json by default)
|
|
465
500
|
poeditor-upload [args...] Upload locale file via PoEditor (reads poeditor/.poeditor.json by default)
|
|
466
501
|
scaffold-vue <target-dir> [--name …] [--slug …] [--force] …
|
|
@@ -488,7 +523,7 @@ const MENU = [
|
|
|
488
523
|
},
|
|
489
524
|
{
|
|
490
525
|
key: '3',
|
|
491
|
-
label: 'Sync configs (vscode, eslint, prettier, tsconfig)',
|
|
526
|
+
label: 'Sync configs (vscode, eslint, prettier, tsconfig, fallow)',
|
|
492
527
|
run: () => runNode('sync-project-configs.mjs'),
|
|
493
528
|
},
|
|
494
529
|
{
|
|
@@ -536,6 +571,11 @@ const MENU = [
|
|
|
536
571
|
label: 'Sync .cursor core coding standards',
|
|
537
572
|
run: () => runNode('sync-core-coding-standards.mjs'),
|
|
538
573
|
},
|
|
574
|
+
{
|
|
575
|
+
key: '13',
|
|
576
|
+
label: 'Fallow analysis',
|
|
577
|
+
run: () => 0,
|
|
578
|
+
},
|
|
539
579
|
]
|
|
540
580
|
|
|
541
581
|
const MAINTAINER_MENU = [
|
|
@@ -633,6 +673,38 @@ async function runInteractiveMenu() {
|
|
|
633
673
|
// Close menu readline before spawning interactive child processes.
|
|
634
674
|
rl.close()
|
|
635
675
|
out = runReleaseScript([bumpType])
|
|
676
|
+
} else if (item.key === '13') {
|
|
677
|
+
let subChoice = 'cancel'
|
|
678
|
+
let selectPrompt = null
|
|
679
|
+
try {
|
|
680
|
+
const inquirerSelect = await import('@inquirer/select')
|
|
681
|
+
selectPrompt = inquirerSelect.default
|
|
682
|
+
} catch {
|
|
683
|
+
// Optional dependency; fail with a clear message if not available.
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
if (selectPrompt) {
|
|
687
|
+
// Close menu readline before running interactive child prompt.
|
|
688
|
+
rl.close()
|
|
689
|
+
subChoice = await selectPrompt({
|
|
690
|
+
message: 'Fallow — choose analysis',
|
|
691
|
+
choices: [
|
|
692
|
+
{ name: 'dead code', value: 'dead-code' },
|
|
693
|
+
{ name: 'Cancel', value: 'cancel' },
|
|
694
|
+
],
|
|
695
|
+
default: 'dead-code',
|
|
696
|
+
})
|
|
697
|
+
} else {
|
|
698
|
+
rl.close()
|
|
699
|
+
console.error('[fg-devkit] Option 13 requires @inquirer/select but it is not available.')
|
|
700
|
+
console.error('[fg-devkit] Run pnpm install in your project and try again.')
|
|
701
|
+
return 1
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (subChoice === 'cancel') {
|
|
705
|
+
return 0
|
|
706
|
+
}
|
|
707
|
+
out = runBundledFallow([subChoice])
|
|
636
708
|
} else {
|
|
637
709
|
// Close menu readline before spawning interactive child processes.
|
|
638
710
|
rl.close()
|
|
@@ -705,6 +777,14 @@ async function main() {
|
|
|
705
777
|
process.exitCode = runBundledTypeScript(rest.length > 0 ? ['--watch', ...rest] : ['--noEmit', '--watch', '-p', 'tsconfig.json'])
|
|
706
778
|
return
|
|
707
779
|
}
|
|
780
|
+
if (sub === 'fallow') {
|
|
781
|
+
process.exitCode = runBundledFallow(rest)
|
|
782
|
+
return
|
|
783
|
+
}
|
|
784
|
+
if (sub === 'dead-code') {
|
|
785
|
+
process.exitCode = runBundledFallow(['dead-code', ...rest])
|
|
786
|
+
return
|
|
787
|
+
}
|
|
708
788
|
const script = DIRECT_COMMANDS[sub]
|
|
709
789
|
if (!script) {
|
|
710
790
|
console.error(`[fg-devkit] Unknown command: ${sub}`)
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* - prettier.config.js — overwritten from fg-devkit prettier sync template
|
|
5
5
|
* - eslint.config.js — overwritten from fg-devkit eslint sync template
|
|
6
6
|
* - tsconfig.json — overwritten from fg-devkit tsconfig app sync template
|
|
7
|
+
* - .fallowrc.json — overwritten from fg-devkit fallow sync template
|
|
7
8
|
*
|
|
8
9
|
* This command is intentionally deterministic: each run rewrites files to the shared templates.
|
|
9
10
|
*
|
|
@@ -46,10 +47,11 @@ if (!fgRoot) {
|
|
|
46
47
|
const prettierSrc = path.join(fgRoot, 'configs', 'prettier.sync-stub.js')
|
|
47
48
|
const eslintStubSrc = path.join(fgRoot, 'configs', 'eslint.sync-stub.js')
|
|
48
49
|
const tsconfigSrc = path.join(fgRoot, 'configs', 'tsconfig.app.sync.json')
|
|
50
|
+
const fallowConfigSrc = path.join(fgRoot, 'configs', 'fallowrc.sync-stub.json')
|
|
49
51
|
|
|
50
|
-
if (!fs.existsSync(prettierSrc) || !fs.existsSync(eslintStubSrc) || !fs.existsSync(tsconfigSrc)) {
|
|
52
|
+
if (!fs.existsSync(prettierSrc) || !fs.existsSync(eslintStubSrc) || !fs.existsSync(tsconfigSrc) || !fs.existsSync(fallowConfigSrc)) {
|
|
51
53
|
console.error(
|
|
52
|
-
'[sync-tooling] Missing prettier.sync-stub.js, eslint.sync-stub.js,
|
|
54
|
+
'[sync-tooling] Missing prettier.sync-stub.js, eslint.sync-stub.js, tsconfig.app.sync.json, or fallowrc.sync-stub.json inside fg-devkit package.',
|
|
53
55
|
)
|
|
54
56
|
process.exit(1)
|
|
55
57
|
}
|
|
@@ -58,7 +60,8 @@ try {
|
|
|
58
60
|
fs.copyFileSync(prettierSrc, path.join(projectRoot, 'prettier.config.js'))
|
|
59
61
|
fs.copyFileSync(eslintStubSrc, path.join(projectRoot, 'eslint.config.js'))
|
|
60
62
|
fs.copyFileSync(tsconfigSrc, path.join(projectRoot, 'tsconfig.json'))
|
|
61
|
-
|
|
63
|
+
fs.copyFileSync(fallowConfigSrc, path.join(projectRoot, '.fallowrc.json'))
|
|
64
|
+
console.log('[sync-tooling] Updated prettier.config.js, eslint.config.js, tsconfig.json, and .fallowrc.json.')
|
|
62
65
|
} catch (err) {
|
|
63
66
|
console.error(`[sync-tooling] ${err.message}`)
|
|
64
67
|
process.exit(1)
|