fg-devkit 1.0.0 → 1.1.0
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 +58 -2
- package/configs/eslint.config.base.js +8 -6
- package/configs/eslint.sync-stub.js +6 -6
- package/configs/prettier.sync-stub.js +6 -0
- package/configs/tsconfig.app.sync.json +2 -26
- package/configs/tsconfig.base.json +11 -0
- package/package.json +16 -17
- package/scripts/fg-devkit.mjs +169 -38
- package/scripts/sync-tooling-configs.mjs +11 -8
package/README.md
CHANGED
|
@@ -4,10 +4,66 @@ Shared settings and tools to improve the developer experience for Vue and TypeSc
|
|
|
4
4
|
|
|
5
5
|
## Quick command alias (zsh)
|
|
6
6
|
|
|
7
|
-
To run `
|
|
7
|
+
To run `fgd` instead of `pnpm exec fg-devkit`, add this alias:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
echo "alias
|
|
10
|
+
echo "alias fgd='pnpm exec fg-devkit'" >> ~/.zshrc && source ~/.zshrc
|
|
11
11
|
```
|
|
12
12
|
|
|
13
13
|
This works in repos where `fg-devkit` is installed.
|
|
14
|
+
|
|
15
|
+
## Bundled ESLint stack
|
|
16
|
+
|
|
17
|
+
`fg-devkit` ships its own ESLint stack (core + parser + plugins), so consuming repos do not need to install ESLint packages just to lint with the shared config.
|
|
18
|
+
|
|
19
|
+
Run lint via CLI:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm exec fgd lint .
|
|
23
|
+
pnpm exec fgd lint-fix .
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Bundled Prettier
|
|
27
|
+
|
|
28
|
+
`fg-devkit` also ships Prettier, so consuming repos can format using the bundled package.
|
|
29
|
+
|
|
30
|
+
Run formatting via CLI:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm exec fgd format
|
|
34
|
+
pnpm exec fgd format-check
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Bundled TypeScript
|
|
38
|
+
|
|
39
|
+
`fg-devkit` ships `vue-tsc` and `typescript`, so consuming repos can run Vue typecheck without installing local TS tooling.
|
|
40
|
+
|
|
41
|
+
Run typecheck via CLI:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm exec fgd typecheck
|
|
45
|
+
pnpm exec fgd typecheck-watch
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## tsconfig in consuming repos
|
|
49
|
+
|
|
50
|
+
Use `fgd sync-project-configs` (or `fgd sync-tooling-configs`) to write the local `tsconfig.json` template from `fg-devkit`.
|
|
51
|
+
|
|
52
|
+
Do not use an extends-only `tsconfig.json` to `fg-devkit/tsconfig.app.sync.json` in consuming repos.
|
|
53
|
+
TypeScript resolves `include`/`exclude` relative to the extended config file location in `node_modules`,
|
|
54
|
+
which can cause `No inputs were found`.
|
|
55
|
+
|
|
56
|
+
The supported approach is: keep a local `tsconfig.json` file in each consuming repo and let sync overwrite
|
|
57
|
+
it with the shared app template.
|
|
58
|
+
|
|
59
|
+
## Minimal local Prettier config for consuming repos
|
|
60
|
+
|
|
61
|
+
Use this as your local `prettier.config.js` to inherit defaults from `fg-devkit`:
|
|
62
|
+
|
|
63
|
+
```js
|
|
64
|
+
import basePrettierConfig from 'fg-devkit/prettier.config.js'
|
|
65
|
+
|
|
66
|
+
export default {
|
|
67
|
+
...basePrettierConfig,
|
|
68
|
+
}
|
|
69
|
+
```
|
|
@@ -3,8 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
import tseslint from '@typescript-eslint/eslint-plugin'
|
|
5
5
|
import tsparser from '@typescript-eslint/parser'
|
|
6
|
+
import pluginI18n from '@intlify/eslint-plugin-vue-i18n'
|
|
6
7
|
import pluginVitest from '@vitest/eslint-plugin'
|
|
7
8
|
import skipFormatting from '@vue/eslint-config-prettier/skip-formatting'
|
|
9
|
+
import pluginPrettier from 'eslint-plugin-prettier'
|
|
8
10
|
import pluginVue from 'eslint-plugin-vue'
|
|
9
11
|
import { globalIgnores } from 'eslint/config'
|
|
10
12
|
import vueParser from 'vue-eslint-parser'
|
|
@@ -23,9 +25,6 @@ export default function createBaseConfig(options = {}) {
|
|
|
23
25
|
additionalSettings = {},
|
|
24
26
|
} = options
|
|
25
27
|
|
|
26
|
-
// Note: Optional plugins should be imported by the consuming project
|
|
27
|
-
// This config accepts them via additionalPlugins option
|
|
28
|
-
|
|
29
28
|
const defaultAdditionalIgnores = [
|
|
30
29
|
'test-results/**',
|
|
31
30
|
'playwright-report/**',
|
|
@@ -130,6 +129,8 @@ export default function createBaseConfig(options = {}) {
|
|
|
130
129
|
files: ['**/*.vue', '**/*.js', '**/*.jsx', '**/*.cjs', '**/*.mjs', '**/*.ts', '**/*.tsx', '**/*.cts', '**/*.mts'],
|
|
131
130
|
plugins: {
|
|
132
131
|
'@typescript-eslint': tseslint,
|
|
132
|
+
...(enablePrettier ? { prettier: pluginPrettier } : {}),
|
|
133
|
+
...(enableI18n ? { '@intlify/vue-i18n': pluginI18n } : {}),
|
|
133
134
|
...additionalPlugins,
|
|
134
135
|
},
|
|
135
136
|
settings: {
|
|
@@ -172,12 +173,13 @@ export default function createBaseConfig(options = {}) {
|
|
|
172
173
|
'no-useless-return': 'error',
|
|
173
174
|
'no-useless-concat': 'error',
|
|
174
175
|
'@typescript-eslint/no-unused-vars': [
|
|
175
|
-
'
|
|
176
|
+
'warn',
|
|
176
177
|
{
|
|
177
178
|
argsIgnorePattern: '^_',
|
|
178
179
|
varsIgnorePattern: '^_',
|
|
179
180
|
},
|
|
180
181
|
],
|
|
182
|
+
'padding-line-between-statements': ['error', { blankLine: 'always', prev: 'export', next: 'export' }],
|
|
181
183
|
'@typescript-eslint/ban-ts-comment': 'off',
|
|
182
184
|
'@typescript-eslint/explicit-function-return-type': 'off',
|
|
183
185
|
'@typescript-eslint/no-var-requires': 'off',
|
|
@@ -197,9 +199,9 @@ export default function createBaseConfig(options = {}) {
|
|
|
197
199
|
'eol-last': 'error',
|
|
198
200
|
'no-lonely-if': 'error',
|
|
199
201
|
// Prettier integration (if enabled and plugin provided)
|
|
200
|
-
...(enablePrettier
|
|
202
|
+
...(enablePrettier ? { 'prettier/prettier': 'warn' } : {}),
|
|
201
203
|
// i18n rules (if enabled and plugin provided)
|
|
202
|
-
...(enableI18n
|
|
204
|
+
...(enableI18n
|
|
203
205
|
? {
|
|
204
206
|
'@intlify/vue-i18n/no-missing-keys': 'error',
|
|
205
207
|
'@intlify/vue-i18n/no-raw-text': [
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Customize locally (plugins, rules) or pass options via createBaseConfig after syncing.
|
|
2
|
+
* ESLint sync template for Vue apps using fg-devkit.
|
|
3
|
+
* Mirrors the previously used project defaults so sync preserves current behavior.
|
|
5
4
|
*/
|
|
6
5
|
import createBaseConfig from 'fg-devkit/eslint.config.base.js'
|
|
7
6
|
import { fileURLToPath } from 'node:url'
|
|
@@ -9,11 +8,12 @@ import { fileURLToPath } from 'node:url'
|
|
|
9
8
|
const tsconfigRootDir = fileURLToPath(new URL('.', import.meta.url))
|
|
10
9
|
|
|
11
10
|
export default [
|
|
12
|
-
{
|
|
13
|
-
ignores: ['.yalc/**', '**/node_modules/**'],
|
|
14
|
-
},
|
|
15
11
|
...createBaseConfig({
|
|
16
12
|
tsconfigRootDir,
|
|
17
13
|
tsconfigFiles: ['./tsconfig.json'],
|
|
14
|
+
extraNonTypeAwareFiles: ['playwright.config.ts', 'poeditor/**/*.ts'],
|
|
15
|
+
enablePrettier: true,
|
|
16
|
+
enableI18n: true,
|
|
17
|
+
i18nLocaleDir: './src/lang/*.json',
|
|
18
18
|
}),
|
|
19
19
|
]
|
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
3
|
"extends": "fg-devkit/tsconfig.base.json",
|
|
4
|
-
"include": [
|
|
5
|
-
"env.d.ts",
|
|
6
|
-
"src/**/*",
|
|
7
|
-
"src/**/*.vue",
|
|
8
|
-
"src/**/*.ts",
|
|
9
|
-
"src/**/*.d.ts",
|
|
10
|
-
"src/vuex.d.ts"
|
|
11
|
-
],
|
|
4
|
+
"include": ["env.d.ts", "src/**/*", "src/**/*.vue", "src/**/*.ts", "src/**/*.d.ts", "src/vuex.d.ts"],
|
|
12
5
|
"exclude": ["src/**/__tests__/*"],
|
|
13
6
|
"compilerOptions": {
|
|
14
|
-
"strict": true,
|
|
15
|
-
"composite": true,
|
|
16
|
-
"noEmit": true,
|
|
17
7
|
"types": ["@intlify/unplugin-vue-i18n/messages", "vue-i18n", "vite/client"],
|
|
18
|
-
"moduleResolution": "bundler",
|
|
19
|
-
"resolvePackageJsonExports": true,
|
|
20
8
|
"paths": {
|
|
21
9
|
"@/*": ["./src/*"],
|
|
22
10
|
"@intlify/*": ["./node_modules/@intlify/*"]
|
|
23
11
|
},
|
|
24
|
-
"baseUrl": "."
|
|
25
|
-
"allowJs": true,
|
|
26
|
-
"esModuleInterop": true,
|
|
27
|
-
"allowSyntheticDefaultImports": true,
|
|
28
|
-
"noUnusedLocals": true,
|
|
29
|
-
"noUnusedParameters": true,
|
|
30
|
-
"skipLibCheck": true,
|
|
31
|
-
"preserveSymlinks": false
|
|
32
|
-
},
|
|
33
|
-
"vueCompilerOptions": {
|
|
34
|
-
"strictTemplates": true,
|
|
35
|
-
"experimentalCompatMode": 2,
|
|
36
|
-
"types": ["fds-vue-core"]
|
|
12
|
+
"baseUrl": "."
|
|
37
13
|
}
|
|
38
14
|
}
|
|
@@ -2,17 +2,28 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
3
|
"extends": "@vue/tsconfig/tsconfig.dom.json",
|
|
4
4
|
"compilerOptions": {
|
|
5
|
+
"target": "ES2022",
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"strict": true,
|
|
8
|
+
"moduleResolution": "bundler",
|
|
9
|
+
"resolvePackageJsonExports": true,
|
|
10
|
+
"noEmit": true,
|
|
11
|
+
"composite": true,
|
|
5
12
|
"skipLibCheck": true,
|
|
6
13
|
"resolveJsonModule": true,
|
|
7
14
|
"allowJs": true,
|
|
15
|
+
"esModuleInterop": true,
|
|
16
|
+
"allowSyntheticDefaultImports": true,
|
|
8
17
|
"noUnusedLocals": true,
|
|
9
18
|
"noUnusedParameters": true,
|
|
19
|
+
"preserveSymlinks": false,
|
|
10
20
|
"paths": {
|
|
11
21
|
"@/*": ["./src/*"]
|
|
12
22
|
}
|
|
13
23
|
},
|
|
14
24
|
"vueCompilerOptions": {
|
|
15
25
|
"strictTemplates": true,
|
|
26
|
+
"experimentalCompatMode": 2,
|
|
16
27
|
"types": ["fds-vue-core"]
|
|
17
28
|
}
|
|
18
29
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fg-devkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Shared configs, scripts, and DX tooling for Vue / TypeScript frontend repos",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
7
7
|
"bin": {
|
|
8
|
-
"
|
|
8
|
+
"fgd": "./scripts/fg-devkit.mjs",
|
|
9
9
|
"fg-devkit": "./scripts/fg-devkit.mjs",
|
|
10
10
|
"fg-vuln-commit": "./scripts/vuln-commit.mjs",
|
|
11
11
|
"fds-vuln-commit": "./scripts/vuln-commit.mjs"
|
|
@@ -48,20 +48,19 @@
|
|
|
48
48
|
"typescript",
|
|
49
49
|
"vue"
|
|
50
50
|
],
|
|
51
|
-
"
|
|
52
|
-
"@
|
|
53
|
-
"@typescript-eslint/
|
|
54
|
-
"@
|
|
55
|
-
"@
|
|
56
|
-
"@vue/
|
|
57
|
-
"
|
|
58
|
-
"eslint
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
}
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@intlify/eslint-plugin-vue-i18n": "4.3.0",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "8.58.2",
|
|
54
|
+
"@typescript-eslint/parser": "8.58.2",
|
|
55
|
+
"@vitest/eslint-plugin": "1.6.16",
|
|
56
|
+
"@vue/eslint-config-prettier": "10.2.0",
|
|
57
|
+
"commitizen": "4.3.1",
|
|
58
|
+
"eslint": "10.2.1",
|
|
59
|
+
"eslint-plugin-prettier": "5.5.5",
|
|
60
|
+
"eslint-plugin-vue": "10.8.0",
|
|
61
|
+
"prettier": "3.8.3",
|
|
62
|
+
"typescript": "5.9.3",
|
|
63
|
+
"vue-eslint-parser": "10.4.0",
|
|
64
|
+
"vue-tsc": "3.2.7"
|
|
66
65
|
}
|
|
67
66
|
}
|
package/scripts/fg-devkit.mjs
CHANGED
|
@@ -5,12 +5,18 @@
|
|
|
5
5
|
* Non-interactive (for scripts and automation):
|
|
6
6
|
* pnpm exec fg-devkit check-deps [policy-file]
|
|
7
7
|
* pnpm exec fg-devkit sync-deps [policy-file]
|
|
8
|
-
* pnpm exec fg-devkit sync-project-configs (VS Code +
|
|
9
|
-
* pnpm exec fg-devkit sync-tooling-configs (
|
|
8
|
+
* pnpm exec fg-devkit sync-project-configs (VS Code + tooling sync; overwrites config files)
|
|
9
|
+
* pnpm exec fg-devkit sync-tooling-configs (tooling sync only; overwrites config files)
|
|
10
10
|
* pnpm exec fg-devkit sync-vscode-settings
|
|
11
11
|
* pnpm exec fg-devkit create-release [patch|minor|major]
|
|
12
12
|
* pnpm exec fg-devkit commit [cz-args...] (Commitizen; uses package.json config.commitizen.path)
|
|
13
13
|
* pnpm exec fg-devkit commit-vuln (staged package.json version bumps → vuln() commit)
|
|
14
|
+
* pnpm exec fg-devkit lint [eslint-args...] (run ESLint with fg-devkit bundled packages)
|
|
15
|
+
* pnpm exec fg-devkit lint-fix [eslint-args...] (same as lint plus --fix)
|
|
16
|
+
* pnpm exec fg-devkit format [prettier-args...] (run Prettier with fg-devkit bundled package)
|
|
17
|
+
* pnpm exec fg-devkit format-check [prettier-args...] (same as format plus --check)
|
|
18
|
+
* pnpm exec fg-devkit typecheck [vue-tsc-args...] (run vue-tsc with fg-devkit bundled package)
|
|
19
|
+
* pnpm exec fg-devkit typecheck-watch [vue-tsc-args...] (same as typecheck plus --watch)
|
|
14
20
|
* Interactive menu (no subcommand):
|
|
15
21
|
* pnpm exec fg-devkit
|
|
16
22
|
*
|
|
@@ -24,8 +30,10 @@ import readline from 'node:readline/promises'
|
|
|
24
30
|
import path from 'node:path'
|
|
25
31
|
import { fileURLToPath } from 'node:url'
|
|
26
32
|
import { stdin as input, stdout as output } from 'node:process'
|
|
33
|
+
import { createRequire } from 'node:module'
|
|
27
34
|
|
|
28
35
|
const scriptDir = path.dirname(fileURLToPath(import.meta.url))
|
|
36
|
+
const require = createRequire(import.meta.url)
|
|
29
37
|
|
|
30
38
|
/** Run another script in this package via Node; inherits stdio and returns the child exit code. */
|
|
31
39
|
function runNode(scriptRelative, args = [], options = {}) {
|
|
@@ -68,37 +76,121 @@ function runReleaseScript(args = []) {
|
|
|
68
76
|
return r.status ?? 1
|
|
69
77
|
}
|
|
70
78
|
|
|
79
|
+
/** Prompt release type in CLI before invoking release.sh to avoid a "stuck" terminal feeling. */
|
|
80
|
+
async function promptReleaseType(rl) {
|
|
81
|
+
console.log('\nSelect release type:')
|
|
82
|
+
console.log(' 1) patch')
|
|
83
|
+
console.log(' 2) minor')
|
|
84
|
+
console.log(' 3) major')
|
|
85
|
+
console.log(' 0) Cancel\n')
|
|
86
|
+
const choice = (await rl.question('Release type [1-3] (default: 1): ')).trim() || '1'
|
|
87
|
+
if (choice === '0') {
|
|
88
|
+
return null
|
|
89
|
+
}
|
|
90
|
+
if (choice === '1') {
|
|
91
|
+
return 'patch'
|
|
92
|
+
}
|
|
93
|
+
if (choice === '2') {
|
|
94
|
+
return 'minor'
|
|
95
|
+
}
|
|
96
|
+
if (choice === '3') {
|
|
97
|
+
return 'major'
|
|
98
|
+
}
|
|
99
|
+
console.error('[fg-devkit] Invalid release type selection.')
|
|
100
|
+
return null
|
|
101
|
+
}
|
|
102
|
+
|
|
71
103
|
/**
|
|
72
|
-
* Run Commitizen
|
|
73
|
-
*
|
|
104
|
+
* Run Commitizen from fg-devkit's bundled dependency set.
|
|
105
|
+
* Uses the consuming repo's config.commitizen.path when present.
|
|
74
106
|
*/
|
|
75
107
|
function runCommitizen(args = []) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
108
|
+
let gitCzBin
|
|
109
|
+
try {
|
|
110
|
+
gitCzBin = require.resolve('commitizen/bin/git-cz')
|
|
111
|
+
} catch {
|
|
112
|
+
console.error('[fg-devkit] Could not resolve bundled commitizen. Reinstall fg-devkit and retry.')
|
|
113
|
+
return 1
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const r = spawnSync(process.execPath, [gitCzBin, ...args], {
|
|
117
|
+
stdio: 'inherit',
|
|
118
|
+
cwd: process.cwd(),
|
|
119
|
+
env: process.env,
|
|
120
|
+
})
|
|
121
|
+
if (r.error) {
|
|
122
|
+
console.error('[fg-devkit]', r.error.message)
|
|
123
|
+
return 1
|
|
124
|
+
}
|
|
125
|
+
return r.status ?? 1
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
/** Run ESLint from fg-devkit's bundled dependency set. */
|
|
130
|
+
function runBundledEslint(args = []) {
|
|
131
|
+
let eslintBin
|
|
132
|
+
try {
|
|
133
|
+
const eslintPkgPath = require.resolve('eslint/package.json')
|
|
134
|
+
eslintBin = path.join(path.dirname(eslintPkgPath), 'bin', 'eslint.js')
|
|
135
|
+
} catch {
|
|
136
|
+
console.error('[fg-devkit] Could not resolve bundled eslint. Reinstall fg-devkit and retry.')
|
|
137
|
+
return 1
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const r = spawnSync(process.execPath, [eslintBin, ...args], {
|
|
141
|
+
stdio: 'inherit',
|
|
142
|
+
cwd: process.cwd(),
|
|
143
|
+
env: process.env,
|
|
144
|
+
})
|
|
145
|
+
if (r.error) {
|
|
146
|
+
console.error('[fg-devkit]', r.error.message)
|
|
147
|
+
return 1
|
|
148
|
+
}
|
|
149
|
+
return r.status ?? 1
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** Run Prettier from fg-devkit's bundled dependency set. */
|
|
153
|
+
function runBundledPrettier(args = []) {
|
|
154
|
+
let prettierBin
|
|
155
|
+
try {
|
|
156
|
+
prettierBin = require.resolve('prettier/bin/prettier.cjs')
|
|
157
|
+
} catch {
|
|
158
|
+
console.error('[fg-devkit] Could not resolve bundled prettier. Reinstall fg-devkit and retry.')
|
|
159
|
+
return 1
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
const r = spawnSync(process.execPath, [prettierBin, ...args], {
|
|
163
|
+
stdio: 'inherit',
|
|
164
|
+
cwd: process.cwd(),
|
|
165
|
+
env: process.env,
|
|
166
|
+
})
|
|
167
|
+
if (r.error) {
|
|
168
|
+
console.error('[fg-devkit]', r.error.message)
|
|
169
|
+
return 1
|
|
170
|
+
}
|
|
171
|
+
return r.status ?? 1
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** Run vue-tsc from fg-devkit's bundled dependency set. */
|
|
175
|
+
function runBundledTypeScript(args = []) {
|
|
176
|
+
let vueTscBin
|
|
177
|
+
try {
|
|
178
|
+
vueTscBin = require.resolve('vue-tsc/bin/vue-tsc.js')
|
|
179
|
+
} catch {
|
|
180
|
+
console.error('[fg-devkit] Could not resolve bundled vue-tsc. Reinstall fg-devkit and retry.')
|
|
181
|
+
return 1
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const r = spawnSync(process.execPath, [vueTscBin, ...args], {
|
|
185
|
+
stdio: 'inherit',
|
|
186
|
+
cwd: process.cwd(),
|
|
187
|
+
env: process.env,
|
|
188
|
+
})
|
|
189
|
+
if (r.error) {
|
|
190
|
+
console.error('[fg-devkit]', r.error.message)
|
|
191
|
+
return 1
|
|
97
192
|
}
|
|
98
|
-
|
|
99
|
-
'[fg-devkit] Commitizen not found. Add devDependency "commitizen", set config.commitizen.path, then retry.',
|
|
100
|
-
)
|
|
101
|
-
return 1
|
|
193
|
+
return r.status ?? 1
|
|
102
194
|
}
|
|
103
195
|
|
|
104
196
|
/** Map subcommand name → script file (extra argv after subcommand is forwarded). */
|
|
@@ -117,13 +209,19 @@ function printHelp() {
|
|
|
117
209
|
Commands:
|
|
118
210
|
check-deps [policy-file] Validate package.json + pins against policy
|
|
119
211
|
sync-deps [policy-file] Align declared versions to policy (existing keys only)
|
|
120
|
-
sync-project-configs VS Code
|
|
121
|
-
sync-tooling-configs
|
|
212
|
+
sync-project-configs VS Code + tooling sync (overwrites config files)
|
|
213
|
+
sync-tooling-configs Tooling sync only (overwrites config files)
|
|
122
214
|
sync-vscode-settings Copy shared VS Code settings into .vscode/settings.json
|
|
123
215
|
create-release [bump] Version bump, git push, GitHub release (patch|minor|major; omit = prompt)
|
|
124
216
|
(alias: createRelease)
|
|
125
217
|
commit [args...] Commitizen (git-cz); uses config.commitizen.path in package.json
|
|
126
218
|
commit-vuln Commit staged dependency bumps as vuln() (alias: vuln-commit)
|
|
219
|
+
lint [eslint-args...] Run ESLint using fg-devkit bundled ESLint stack
|
|
220
|
+
lint-fix [eslint-args...] Run ESLint with --fix using fg-devkit bundled ESLint stack
|
|
221
|
+
format [prettier-args...] Run Prettier using fg-devkit bundled package
|
|
222
|
+
format-check [prettier-args...] Run Prettier with --check using fg-devkit bundled package
|
|
223
|
+
typecheck [vue-tsc-args...] Run vue-tsc using fg-devkit bundled package
|
|
224
|
+
typecheck-watch [vue-tsc-args...] Run vue-tsc with --watch using fg-devkit bundled package
|
|
127
225
|
|
|
128
226
|
With no command, opens an interactive menu.
|
|
129
227
|
|
|
@@ -135,32 +233,32 @@ Options:
|
|
|
135
233
|
const MENU = [
|
|
136
234
|
{
|
|
137
235
|
key: '1',
|
|
138
|
-
label: 'Check dependency policy
|
|
236
|
+
label: 'Check dependency policy',
|
|
139
237
|
run: () => runNode('check-dependency-policy.mjs'),
|
|
140
238
|
},
|
|
141
239
|
{
|
|
142
240
|
key: '2',
|
|
143
|
-
label: 'Sync dependency
|
|
241
|
+
label: 'Sync dependency policy',
|
|
144
242
|
run: () => runNode('sync-dependency-policy.mjs'),
|
|
145
243
|
},
|
|
146
244
|
{
|
|
147
245
|
key: '3',
|
|
148
|
-
label: 'Sync
|
|
246
|
+
label: 'Sync configs (vscode, eslint, prettier, tsconfig)',
|
|
149
247
|
run: () => runNode('sync-project-configs.mjs'),
|
|
150
248
|
},
|
|
151
249
|
{
|
|
152
250
|
key: '4',
|
|
153
|
-
label: 'Create release
|
|
251
|
+
label: 'Create release',
|
|
154
252
|
run: () => runReleaseScript(),
|
|
155
253
|
},
|
|
156
254
|
{
|
|
157
255
|
key: '5',
|
|
158
|
-
label: 'Commit (Commitizen
|
|
256
|
+
label: 'Commit (Commitizen)',
|
|
159
257
|
run: () => runCommitizen(),
|
|
160
258
|
},
|
|
161
259
|
{
|
|
162
260
|
key: '6',
|
|
163
|
-
label: 'Commit vulnerability
|
|
261
|
+
label: 'Commit vulnerability (Commitizen)',
|
|
164
262
|
run: () => runNode('vuln-commit.mjs'),
|
|
165
263
|
},
|
|
166
264
|
]
|
|
@@ -191,7 +289,16 @@ async function runInteractiveMenu() {
|
|
|
191
289
|
|
|
192
290
|
let exitCode = 0
|
|
193
291
|
try {
|
|
194
|
-
|
|
292
|
+
let out
|
|
293
|
+
if (item.key === '4') {
|
|
294
|
+
const bumpType = await promptReleaseType(rl)
|
|
295
|
+
if (!bumpType) {
|
|
296
|
+
return 0
|
|
297
|
+
}
|
|
298
|
+
out = runReleaseScript([bumpType])
|
|
299
|
+
} else {
|
|
300
|
+
out = item.run()
|
|
301
|
+
}
|
|
195
302
|
if (typeof out === 'object' && out !== null && typeof out.then === 'function') {
|
|
196
303
|
exitCode = await out
|
|
197
304
|
} else if (typeof out === 'number') {
|
|
@@ -224,6 +331,30 @@ async function main() {
|
|
|
224
331
|
process.exitCode = runNode('vuln-commit.mjs', rest)
|
|
225
332
|
return
|
|
226
333
|
}
|
|
334
|
+
if (sub === 'lint') {
|
|
335
|
+
process.exitCode = runBundledEslint(rest.length > 0 ? rest : ['.'])
|
|
336
|
+
return
|
|
337
|
+
}
|
|
338
|
+
if (sub === 'lint-fix') {
|
|
339
|
+
process.exitCode = runBundledEslint(rest.length > 0 ? ['--fix', ...rest] : ['--fix', '.'])
|
|
340
|
+
return
|
|
341
|
+
}
|
|
342
|
+
if (sub === 'format') {
|
|
343
|
+
process.exitCode = runBundledPrettier(rest.length > 0 ? rest : ['--write', '.'])
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
if (sub === 'format-check') {
|
|
347
|
+
process.exitCode = runBundledPrettier(rest.length > 0 ? ['--check', ...rest] : ['--check', '.'])
|
|
348
|
+
return
|
|
349
|
+
}
|
|
350
|
+
if (sub === 'typecheck') {
|
|
351
|
+
process.exitCode = runBundledTypeScript(rest.length > 0 ? rest : ['--noEmit', '-p', 'tsconfig.json'])
|
|
352
|
+
return
|
|
353
|
+
}
|
|
354
|
+
if (sub === 'typecheck-watch') {
|
|
355
|
+
process.exitCode = runBundledTypeScript(rest.length > 0 ? ['--watch', ...rest] : ['--noEmit', '--watch', '-p', 'tsconfig.json'])
|
|
356
|
+
return
|
|
357
|
+
}
|
|
227
358
|
const script = DIRECT_COMMANDS[sub]
|
|
228
359
|
if (!script) {
|
|
229
360
|
console.error(`[fg-devkit] Unknown command: ${sub}`)
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Syncs shared tooling files from fg-devkit into the repo root:
|
|
4
|
-
* - prettier.config.js —
|
|
5
|
-
* - eslint.config.js —
|
|
6
|
-
* - tsconfig.json —
|
|
7
|
-
*
|
|
4
|
+
* - prettier.config.js — overwritten from fg-devkit prettier sync template
|
|
5
|
+
* - eslint.config.js — overwritten from fg-devkit eslint sync template
|
|
6
|
+
* - tsconfig.json — overwritten from fg-devkit tsconfig app sync template
|
|
7
|
+
*
|
|
8
|
+
* This command is intentionally deterministic: each run rewrites files to the shared templates.
|
|
8
9
|
*
|
|
9
10
|
* Requires fg-devkit on disk (direct dependency or via fds-vue-core).
|
|
10
11
|
*
|
|
@@ -15,11 +16,14 @@
|
|
|
15
16
|
|
|
16
17
|
import fs from 'node:fs'
|
|
17
18
|
import path from 'node:path'
|
|
19
|
+
import { fileURLToPath } from 'node:url'
|
|
18
20
|
|
|
19
21
|
const projectRoot = process.cwd()
|
|
22
|
+
const scriptDir = path.dirname(fileURLToPath(import.meta.url))
|
|
20
23
|
|
|
21
24
|
function findFgDevkitPackageRoot() {
|
|
22
25
|
const candidates = [
|
|
26
|
+
path.resolve(scriptDir, '..'),
|
|
23
27
|
path.join(projectRoot, 'node_modules', 'fg-devkit'),
|
|
24
28
|
path.join(projectRoot, 'node_modules', 'fds-vue-core', 'node_modules', 'fg-devkit'),
|
|
25
29
|
]
|
|
@@ -39,13 +43,13 @@ if (!fgRoot) {
|
|
|
39
43
|
process.exit(1)
|
|
40
44
|
}
|
|
41
45
|
|
|
42
|
-
const prettierSrc = path.join(fgRoot, 'configs', 'prettier.
|
|
46
|
+
const prettierSrc = path.join(fgRoot, 'configs', 'prettier.sync-stub.js')
|
|
43
47
|
const eslintStubSrc = path.join(fgRoot, 'configs', 'eslint.sync-stub.js')
|
|
44
48
|
const tsconfigSrc = path.join(fgRoot, 'configs', 'tsconfig.app.sync.json')
|
|
45
49
|
|
|
46
50
|
if (!fs.existsSync(prettierSrc) || !fs.existsSync(eslintStubSrc) || !fs.existsSync(tsconfigSrc)) {
|
|
47
51
|
console.error(
|
|
48
|
-
'[sync-tooling] Missing prettier.
|
|
52
|
+
'[sync-tooling] Missing prettier.sync-stub.js, eslint.sync-stub.js, or tsconfig.app.sync.json inside fg-devkit package.',
|
|
49
53
|
)
|
|
50
54
|
process.exit(1)
|
|
51
55
|
}
|
|
@@ -54,9 +58,8 @@ try {
|
|
|
54
58
|
fs.copyFileSync(prettierSrc, path.join(projectRoot, 'prettier.config.js'))
|
|
55
59
|
fs.copyFileSync(eslintStubSrc, path.join(projectRoot, 'eslint.config.js'))
|
|
56
60
|
fs.copyFileSync(tsconfigSrc, path.join(projectRoot, 'tsconfig.json'))
|
|
61
|
+
console.log('[sync-tooling] Updated prettier.config.js, eslint.config.js, and tsconfig.json.')
|
|
57
62
|
} catch (err) {
|
|
58
63
|
console.error(`[sync-tooling] ${err.message}`)
|
|
59
64
|
process.exit(1)
|
|
60
65
|
}
|
|
61
|
-
|
|
62
|
-
console.log('[sync-tooling] Updated prettier.config.js, eslint.config.js, and tsconfig.json.')
|