fg-devkit 1.0.0 → 1.1.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/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 +12 -4
- package/configs/tsconfig.vue-base.json +22 -0
- package/configs/tsconfig.vue-dom.json +8 -0
- package/package.json +21 -16
- package/scripts/cz/cz-adapter.cjs +2 -0
- package/scripts/fg-devkit.mjs +202 -50
- 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
|
}
|
|
@@ -1,18 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"extends": "
|
|
3
|
+
"extends": "./tsconfig.vue-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,
|
|
10
|
-
"
|
|
11
|
-
"@/*": ["./src/*"]
|
|
12
|
-
}
|
|
19
|
+
"preserveSymlinks": false
|
|
13
20
|
},
|
|
14
21
|
"vueCompilerOptions": {
|
|
15
22
|
"strictTemplates": true,
|
|
23
|
+
"experimentalCompatMode": 2,
|
|
16
24
|
"types": ["fds-vue-core"]
|
|
17
25
|
}
|
|
18
26
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"noEmit": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"moduleResolution": "bundler",
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"allowImportingTsExtensions": true,
|
|
9
|
+
"moduleDetection": "force",
|
|
10
|
+
"jsx": "preserve",
|
|
11
|
+
"jsxImportSource": "vue",
|
|
12
|
+
"noImplicitThis": true,
|
|
13
|
+
"strict": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"target": "ESNext",
|
|
16
|
+
"useDefineForClassFields": true,
|
|
17
|
+
"esModuleInterop": true,
|
|
18
|
+
"forceConsistentCasingInFileNames": true,
|
|
19
|
+
"libReplacement": false,
|
|
20
|
+
"skipLibCheck": true
|
|
21
|
+
}
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fg-devkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
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,25 @@
|
|
|
48
48
|
"typescript",
|
|
49
49
|
"vue"
|
|
50
50
|
],
|
|
51
|
-
"
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
"@vitest/eslint-plugin": "^1.5.0",
|
|
55
|
-
"@vue/eslint-config-prettier": "^10.0.0",
|
|
56
|
-
"@vue/tsconfig": "^0.8.0",
|
|
57
|
-
"eslint": "^9.0.0 || ^10.0.0",
|
|
58
|
-
"eslint-plugin-vue": "^10.0.0",
|
|
59
|
-
"typescript": ">=5.0.0",
|
|
60
|
-
"vue-eslint-parser": "^10.0.0"
|
|
61
|
-
},
|
|
62
|
-
"peerDependenciesMeta": {
|
|
63
|
-
"@vitest/eslint-plugin": {
|
|
64
|
-
"optional": true
|
|
51
|
+
"config": {
|
|
52
|
+
"commitizen": {
|
|
53
|
+
"path": "./scripts/cz/cz-adapter.cjs"
|
|
65
54
|
}
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@intlify/eslint-plugin-vue-i18n": "4.3.0",
|
|
58
|
+
"@typescript-eslint/eslint-plugin": "8.58.2",
|
|
59
|
+
"@typescript-eslint/parser": "8.58.2",
|
|
60
|
+
"@vitest/eslint-plugin": "1.6.16",
|
|
61
|
+
"@vue/eslint-config-prettier": "10.2.0",
|
|
62
|
+
"@vue/tsconfig": "0.9.1",
|
|
63
|
+
"commitizen": "4.3.1",
|
|
64
|
+
"eslint": "10.2.1",
|
|
65
|
+
"eslint-plugin-prettier": "5.5.5",
|
|
66
|
+
"eslint-plugin-vue": "10.8.0",
|
|
67
|
+
"prettier": "3.8.3",
|
|
68
|
+
"typescript": "5.9.3",
|
|
69
|
+
"vue-eslint-parser": "10.4.0",
|
|
70
|
+
"vue-tsc": "3.2.7"
|
|
66
71
|
}
|
|
67
72
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
module.exports = {
|
|
6
6
|
prompter(cz, commit) {
|
|
7
|
+
const defaultType = process.env.FG_DEVKIT_CZ_DEFAULT_TYPE;
|
|
7
8
|
const types = [
|
|
8
9
|
{ value: "feat", name: "feat(scope): Added" },
|
|
9
10
|
{ value: "fix", name: "fix(scope): Fixed" },
|
|
@@ -22,6 +23,7 @@ module.exports = {
|
|
|
22
23
|
name: "change_type",
|
|
23
24
|
message: "Select the type of change you are committing",
|
|
24
25
|
choices: types,
|
|
26
|
+
default: defaultType && types.some((t) => t.value === defaultType) ? defaultType : undefined,
|
|
25
27
|
},
|
|
26
28
|
{
|
|
27
29
|
type: "input",
|
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
|
-
* pnpm exec fg-devkit commit [cz-args...] (Commitizen; uses
|
|
12
|
+
* pnpm exec fg-devkit commit [cz-args...] (Commitizen; uses fg-devkit bundled cz adapter)
|
|
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,140 @@ 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
|
+
* Always forces fg-devkit's bundled cz adapter so it stays interactive.
|
|
74
106
|
*/
|
|
75
|
-
function runCommitizen(args = []) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
()
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
107
|
+
function runCommitizen(args = [], extraEnv = {}) {
|
|
108
|
+
let bootstrapBin
|
|
109
|
+
let commitizenPkgDir
|
|
110
|
+
const adapterPath = path.join(scriptDir, 'cz', 'cz-adapter.cjs')
|
|
111
|
+
try {
|
|
112
|
+
bootstrapBin = require.resolve('commitizen/dist/cli/git-cz.js')
|
|
113
|
+
commitizenPkgDir = path.dirname(require.resolve('commitizen/package.json'))
|
|
114
|
+
} catch {
|
|
115
|
+
console.error('[fg-devkit] Could not resolve bundled commitizen. Reinstall fg-devkit and retry.')
|
|
116
|
+
return 1
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const launcher = `
|
|
120
|
+
const { bootstrap } = require(${JSON.stringify(bootstrapBin)});
|
|
121
|
+
const argv = ['node', 'git-cz', ...JSON.parse(process.env.FG_DEVKIT_CZ_ARGS || '[]')];
|
|
122
|
+
bootstrap(
|
|
123
|
+
{
|
|
124
|
+
cliPath: ${JSON.stringify(commitizenPkgDir)},
|
|
125
|
+
config: { path: ${JSON.stringify(adapterPath)} },
|
|
126
|
+
},
|
|
127
|
+
argv
|
|
128
|
+
);
|
|
129
|
+
`
|
|
130
|
+
|
|
131
|
+
const r = spawnSync(process.execPath, ['-e', launcher], {
|
|
132
|
+
stdio: 'inherit',
|
|
133
|
+
cwd: process.cwd(),
|
|
134
|
+
env: {
|
|
135
|
+
...process.env,
|
|
136
|
+
FG_DEVKIT_CZ_ARGS: JSON.stringify(args),
|
|
137
|
+
...extraEnv,
|
|
138
|
+
},
|
|
139
|
+
})
|
|
140
|
+
if (r.error) {
|
|
141
|
+
console.error('[fg-devkit]', r.error.message)
|
|
142
|
+
return 1
|
|
143
|
+
}
|
|
144
|
+
return r.status ?? 1
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
/** Run ESLint from fg-devkit's bundled dependency set. */
|
|
149
|
+
function runBundledEslint(args = []) {
|
|
150
|
+
let eslintBin
|
|
151
|
+
try {
|
|
152
|
+
const eslintPkgPath = require.resolve('eslint/package.json')
|
|
153
|
+
eslintBin = path.join(path.dirname(eslintPkgPath), 'bin', 'eslint.js')
|
|
154
|
+
} catch {
|
|
155
|
+
console.error('[fg-devkit] Could not resolve bundled eslint. Reinstall fg-devkit and retry.')
|
|
156
|
+
return 1
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const r = spawnSync(process.execPath, [eslintBin, ...args], {
|
|
160
|
+
stdio: 'inherit',
|
|
161
|
+
cwd: process.cwd(),
|
|
162
|
+
env: process.env,
|
|
163
|
+
})
|
|
164
|
+
if (r.error) {
|
|
165
|
+
console.error('[fg-devkit]', r.error.message)
|
|
166
|
+
return 1
|
|
167
|
+
}
|
|
168
|
+
return r.status ?? 1
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/** Run Prettier from fg-devkit's bundled dependency set. */
|
|
172
|
+
function runBundledPrettier(args = []) {
|
|
173
|
+
let prettierBin
|
|
174
|
+
try {
|
|
175
|
+
prettierBin = require.resolve('prettier/bin/prettier.cjs')
|
|
176
|
+
} catch {
|
|
177
|
+
console.error('[fg-devkit] Could not resolve bundled prettier. Reinstall fg-devkit and retry.')
|
|
178
|
+
return 1
|
|
97
179
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
180
|
+
|
|
181
|
+
const r = spawnSync(process.execPath, [prettierBin, ...args], {
|
|
182
|
+
stdio: 'inherit',
|
|
183
|
+
cwd: process.cwd(),
|
|
184
|
+
env: process.env,
|
|
185
|
+
})
|
|
186
|
+
if (r.error) {
|
|
187
|
+
console.error('[fg-devkit]', r.error.message)
|
|
188
|
+
return 1
|
|
189
|
+
}
|
|
190
|
+
return r.status ?? 1
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Run vue-tsc from fg-devkit's bundled dependency set. */
|
|
194
|
+
function runBundledTypeScript(args = []) {
|
|
195
|
+
let vueTscBin
|
|
196
|
+
try {
|
|
197
|
+
vueTscBin = require.resolve('vue-tsc/bin/vue-tsc.js')
|
|
198
|
+
} catch {
|
|
199
|
+
console.error('[fg-devkit] Could not resolve bundled vue-tsc. Reinstall fg-devkit and retry.')
|
|
200
|
+
return 1
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
const r = spawnSync(process.execPath, [vueTscBin, ...args], {
|
|
204
|
+
stdio: 'inherit',
|
|
205
|
+
cwd: process.cwd(),
|
|
206
|
+
env: process.env,
|
|
207
|
+
})
|
|
208
|
+
if (r.error) {
|
|
209
|
+
console.error('[fg-devkit]', r.error.message)
|
|
210
|
+
return 1
|
|
211
|
+
}
|
|
212
|
+
return r.status ?? 1
|
|
102
213
|
}
|
|
103
214
|
|
|
104
215
|
/** Map subcommand name → script file (extra argv after subcommand is forwarded). */
|
|
@@ -117,13 +228,19 @@ function printHelp() {
|
|
|
117
228
|
Commands:
|
|
118
229
|
check-deps [policy-file] Validate package.json + pins against policy
|
|
119
230
|
sync-deps [policy-file] Align declared versions to policy (existing keys only)
|
|
120
|
-
sync-project-configs VS Code
|
|
121
|
-
sync-tooling-configs
|
|
231
|
+
sync-project-configs VS Code + tooling sync (overwrites config files)
|
|
232
|
+
sync-tooling-configs Tooling sync only (overwrites config files)
|
|
122
233
|
sync-vscode-settings Copy shared VS Code settings into .vscode/settings.json
|
|
123
234
|
create-release [bump] Version bump, git push, GitHub release (patch|minor|major; omit = prompt)
|
|
124
235
|
(alias: createRelease)
|
|
125
|
-
commit [args...] Commitizen (git-cz)
|
|
236
|
+
commit [args...] Commitizen (git-cz) with fg-devkit bundled adapter
|
|
126
237
|
commit-vuln Commit staged dependency bumps as vuln() (alias: vuln-commit)
|
|
238
|
+
lint [eslint-args...] Run ESLint using fg-devkit bundled ESLint stack
|
|
239
|
+
lint-fix [eslint-args...] Run ESLint with --fix using fg-devkit bundled ESLint stack
|
|
240
|
+
format [prettier-args...] Run Prettier using fg-devkit bundled package
|
|
241
|
+
format-check [prettier-args...] Run Prettier with --check using fg-devkit bundled package
|
|
242
|
+
typecheck [vue-tsc-args...] Run vue-tsc using fg-devkit bundled package
|
|
243
|
+
typecheck-watch [vue-tsc-args...] Run vue-tsc with --watch using fg-devkit bundled package
|
|
127
244
|
|
|
128
245
|
With no command, opens an interactive menu.
|
|
129
246
|
|
|
@@ -135,33 +252,33 @@ Options:
|
|
|
135
252
|
const MENU = [
|
|
136
253
|
{
|
|
137
254
|
key: '1',
|
|
138
|
-
label: 'Check dependency policy
|
|
255
|
+
label: 'Check dependency policy',
|
|
139
256
|
run: () => runNode('check-dependency-policy.mjs'),
|
|
140
257
|
},
|
|
141
258
|
{
|
|
142
259
|
key: '2',
|
|
143
|
-
label: 'Sync dependency
|
|
260
|
+
label: 'Sync dependency policy',
|
|
144
261
|
run: () => runNode('sync-dependency-policy.mjs'),
|
|
145
262
|
},
|
|
146
263
|
{
|
|
147
264
|
key: '3',
|
|
148
|
-
label: 'Sync
|
|
265
|
+
label: 'Sync configs (vscode, eslint, prettier, tsconfig)',
|
|
149
266
|
run: () => runNode('sync-project-configs.mjs'),
|
|
150
267
|
},
|
|
151
268
|
{
|
|
152
269
|
key: '4',
|
|
153
|
-
label: 'Create release
|
|
270
|
+
label: 'Create release',
|
|
154
271
|
run: () => runReleaseScript(),
|
|
155
272
|
},
|
|
156
273
|
{
|
|
157
274
|
key: '5',
|
|
158
|
-
label: 'Commit (Commitizen
|
|
275
|
+
label: 'Commit (Commitizen)',
|
|
159
276
|
run: () => runCommitizen(),
|
|
160
277
|
},
|
|
161
278
|
{
|
|
162
279
|
key: '6',
|
|
163
|
-
label: 'Commit vulnerability
|
|
164
|
-
run: () =>
|
|
280
|
+
label: 'Commit vulnerability (Commitizen)',
|
|
281
|
+
run: () => runCommitizen([], { FG_DEVKIT_CZ_DEFAULT_TYPE: 'vuln' }),
|
|
165
282
|
},
|
|
166
283
|
]
|
|
167
284
|
|
|
@@ -189,18 +306,29 @@ async function runInteractiveMenu() {
|
|
|
189
306
|
return 1
|
|
190
307
|
}
|
|
191
308
|
|
|
192
|
-
let
|
|
193
|
-
|
|
194
|
-
const
|
|
195
|
-
if (
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
exitCode = out
|
|
309
|
+
let out
|
|
310
|
+
if (item.key === '4') {
|
|
311
|
+
const bumpType = await promptReleaseType(rl)
|
|
312
|
+
if (!bumpType) {
|
|
313
|
+
rl.close()
|
|
314
|
+
return 0
|
|
199
315
|
}
|
|
200
|
-
|
|
316
|
+
// Close menu readline before spawning interactive child processes.
|
|
317
|
+
rl.close()
|
|
318
|
+
out = runReleaseScript([bumpType])
|
|
319
|
+
} else {
|
|
320
|
+
// Close menu readline before spawning interactive child processes.
|
|
201
321
|
rl.close()
|
|
322
|
+
out = item.run()
|
|
202
323
|
}
|
|
203
|
-
|
|
324
|
+
|
|
325
|
+
if (typeof out === 'object' && out !== null && typeof out.then === 'function') {
|
|
326
|
+
return await out
|
|
327
|
+
}
|
|
328
|
+
if (typeof out === 'number') {
|
|
329
|
+
return out
|
|
330
|
+
}
|
|
331
|
+
return 0
|
|
204
332
|
}
|
|
205
333
|
|
|
206
334
|
async function main() {
|
|
@@ -224,6 +352,30 @@ async function main() {
|
|
|
224
352
|
process.exitCode = runNode('vuln-commit.mjs', rest)
|
|
225
353
|
return
|
|
226
354
|
}
|
|
355
|
+
if (sub === 'lint') {
|
|
356
|
+
process.exitCode = runBundledEslint(rest.length > 0 ? rest : ['.'])
|
|
357
|
+
return
|
|
358
|
+
}
|
|
359
|
+
if (sub === 'lint-fix') {
|
|
360
|
+
process.exitCode = runBundledEslint(rest.length > 0 ? ['--fix', ...rest] : ['--fix', '.'])
|
|
361
|
+
return
|
|
362
|
+
}
|
|
363
|
+
if (sub === 'format') {
|
|
364
|
+
process.exitCode = runBundledPrettier(rest.length > 0 ? rest : ['--write', '.'])
|
|
365
|
+
return
|
|
366
|
+
}
|
|
367
|
+
if (sub === 'format-check') {
|
|
368
|
+
process.exitCode = runBundledPrettier(rest.length > 0 ? ['--check', ...rest] : ['--check', '.'])
|
|
369
|
+
return
|
|
370
|
+
}
|
|
371
|
+
if (sub === 'typecheck') {
|
|
372
|
+
process.exitCode = runBundledTypeScript(rest.length > 0 ? rest : ['--noEmit', '-p', 'tsconfig.json'])
|
|
373
|
+
return
|
|
374
|
+
}
|
|
375
|
+
if (sub === 'typecheck-watch') {
|
|
376
|
+
process.exitCode = runBundledTypeScript(rest.length > 0 ? ['--watch', ...rest] : ['--noEmit', '--watch', '-p', 'tsconfig.json'])
|
|
377
|
+
return
|
|
378
|
+
}
|
|
227
379
|
const script = DIRECT_COMMANDS[sub]
|
|
228
380
|
if (!script) {
|
|
229
381
|
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.')
|