fg-devkit 1.7.1 → 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 +69 -0
- package/configs/dependency-policy.vue-workspace.json +4 -4
- package/configs/fallowrc.sync-stub.json +13 -0
- package/package.json +4 -1
- package/scaffold/vue/package.json +1 -1
- package/scripts/fg-devkit.mjs +83 -3
- package/scripts/fleet-bump-fg-devkit.mjs +26 -1
- package/scripts/poeditor-upload.mjs +58 -2
- package/scripts/refresh-dependency-policy-from-repos.mjs +0 -2
- package/scripts/sync-tooling-configs.mjs +6 -3
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,3 +154,54 @@ 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
|
+
|
|
184
|
+
## Install CLI in this repo
|
|
185
|
+
|
|
186
|
+
1) Add this to your shell config (`~/.zshrc`) and update `FGD_DEVKIT_PATH`:
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
cat <<'EOF' >> ~/.zshrc
|
|
190
|
+
# Smart fgd: use local project binary when available, otherwise fg-devkit script
|
|
191
|
+
unalias fgd 2>/dev/null
|
|
192
|
+
export FGD_DEVKIT_PATH="/Users/username/projects/fg-devkit"
|
|
193
|
+
fgd() {
|
|
194
|
+
if [ -x "./node_modules/.bin/fgd" ]; then
|
|
195
|
+
pnpm exec fgd "$@"
|
|
196
|
+
else
|
|
197
|
+
node "$FGD_DEVKIT_PATH/scripts/fg-devkit.mjs" "$@"
|
|
198
|
+
fi
|
|
199
|
+
}
|
|
200
|
+
EOF
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
2) Reload shell config:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
source ~/.zshrc
|
|
207
|
+
```
|
|
@@ -6,10 +6,10 @@
|
|
|
6
6
|
"@lexical/list": "0.30.0",
|
|
7
7
|
"@lexical/rich-text": "0.30.0",
|
|
8
8
|
"@piwikpro/vue-piwik-pro": "1.4.0",
|
|
9
|
-
"@sentry/browser": "
|
|
10
|
-
"@sentry/tracing": "7.
|
|
11
|
-
"@sentry/vue": "
|
|
12
|
-
"@sentry/wasm": "
|
|
9
|
+
"@sentry/browser": "10.50.0",
|
|
10
|
+
"@sentry/tracing": "7.120.4",
|
|
11
|
+
"@sentry/vue": "10.50.0",
|
|
12
|
+
"@sentry/wasm": "10.50.0",
|
|
13
13
|
"@tailwindcss/postcss": "4.2.4",
|
|
14
14
|
"@tanstack/vue-query": "5.99.2",
|
|
15
15
|
"@types/leaflet": "1.5.7",
|
|
@@ -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',
|
|
@@ -440,7 +473,7 @@ Commands:
|
|
|
440
473
|
fleet-vulns [projects-root] [--summary-only] [--delay-ms=<ms>]
|
|
441
474
|
Run pnpm audit across Vue repos (full output + combined summary)
|
|
442
475
|
fleet-bump-fg-devkit [projects-root] [--dry-run]
|
|
443
|
-
Bump fg-devkit
|
|
476
|
+
Bump fg-devkit, run sync-deps, then pnpm install across Vue repos
|
|
444
477
|
policy-upgrade [policy-file] [ncu-args...]
|
|
445
478
|
Upgrade policy packages via npm-check-updates (default interactive)
|
|
446
479
|
sync-project-configs VS Code + tooling sync (overwrites config files)
|
|
@@ -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 = [
|
|
@@ -576,7 +616,7 @@ const MAINTAINER_MENU = [
|
|
|
576
616
|
},
|
|
577
617
|
{
|
|
578
618
|
key: 'm8',
|
|
579
|
-
label: 'Maintainer: Bump fg-devkit in all Vue repos and
|
|
619
|
+
label: 'Maintainer: Bump fg-devkit in all Vue repos, run sync-deps, and pnpm install',
|
|
580
620
|
run: () => runNode('fleet-bump-fg-devkit.mjs'),
|
|
581
621
|
},
|
|
582
622
|
]
|
|
@@ -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}`)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Bumps fg-devkit to latest in Vue repositories and runs pnpm install.
|
|
3
|
+
* Bumps fg-devkit to latest in Vue repositories, syncs dependency policy, and runs pnpm install.
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* pnpm exec fg-devkit fleet-bump-fg-devkit [projects-root] [--dry-run]
|
|
@@ -82,10 +82,12 @@ let updated = 0
|
|
|
82
82
|
for (const repoDir of uniqueRepos) {
|
|
83
83
|
const repoName = path.basename(repoDir)
|
|
84
84
|
const bumpArgs = ['up', 'fg-devkit@latest']
|
|
85
|
+
const syncDepsArgs = ['exec', 'fg-devkit', 'sync-deps']
|
|
85
86
|
const installArgs = ['install']
|
|
86
87
|
|
|
87
88
|
if (dryRun) {
|
|
88
89
|
console.log(`[fleet-bump-fg-devkit] DRY RUN ${repoName}: pnpm ${bumpArgs.join(' ')}`)
|
|
90
|
+
console.log(`[fleet-bump-fg-devkit] DRY RUN ${repoName}: pnpm ${syncDepsArgs.join(' ')}`)
|
|
89
91
|
console.log(`[fleet-bump-fg-devkit] DRY RUN ${repoName}: pnpm ${installArgs.join(' ')}`)
|
|
90
92
|
continue
|
|
91
93
|
}
|
|
@@ -114,6 +116,29 @@ for (const repoDir of uniqueRepos) {
|
|
|
114
116
|
continue
|
|
115
117
|
}
|
|
116
118
|
|
|
119
|
+
const syncDeps = spawnSync('pnpm', syncDepsArgs, {
|
|
120
|
+
cwd: repoDir,
|
|
121
|
+
stdio: 'inherit',
|
|
122
|
+
env: {
|
|
123
|
+
...process.env,
|
|
124
|
+
npm_config_save_prefix: '',
|
|
125
|
+
npm_config_save_exact: 'true',
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
if (syncDeps.error) {
|
|
130
|
+
failures += 1
|
|
131
|
+
console.error(`[fleet-bump-fg-devkit] FAIL ${repoName}: ${syncDeps.error.message}`)
|
|
132
|
+
continue
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const syncDepsStatus = syncDeps.status ?? 1
|
|
136
|
+
if (syncDepsStatus !== 0) {
|
|
137
|
+
failures += 1
|
|
138
|
+
console.error(`[fleet-bump-fg-devkit] FAIL ${repoName}: sync-deps exited with code ${syncDepsStatus}`)
|
|
139
|
+
continue
|
|
140
|
+
}
|
|
141
|
+
|
|
117
142
|
const install = spawnSync('pnpm', installArgs, {
|
|
118
143
|
cwd: repoDir,
|
|
119
144
|
stdio: 'inherit',
|
|
@@ -12,6 +12,29 @@ import path from 'node:path'
|
|
|
12
12
|
|
|
13
13
|
import { getFlagValue, getPoeditorToken, loadPoeditorConfig, parseFlags, resolvePathFromCwd } from './poeditor-common.mjs'
|
|
14
14
|
|
|
15
|
+
const MIN_UPLOAD_INTERVAL_MS = 20_000
|
|
16
|
+
const MAX_UPLOAD_RETRIES = 3
|
|
17
|
+
const RETRYABLE_UPLOAD_ERROR_CODES = new Set(['4048'])
|
|
18
|
+
|
|
19
|
+
function sleep(ms) {
|
|
20
|
+
return new Promise((resolve) => {
|
|
21
|
+
setTimeout(resolve, ms)
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function parsePoeditorError(err) {
|
|
26
|
+
const message = err instanceof Error ? err.message : String(err)
|
|
27
|
+
const match = message.match(/Upload failed:\s*(\{.*\})$/)
|
|
28
|
+
if (!match) return null
|
|
29
|
+
try {
|
|
30
|
+
const payload = JSON.parse(match[1])
|
|
31
|
+
const code = payload?.response?.code
|
|
32
|
+
return typeof code === 'string' ? code : null
|
|
33
|
+
} catch {
|
|
34
|
+
return null
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
15
38
|
function getUploadType(filePath) {
|
|
16
39
|
const extension = path.extname(filePath).toLowerCase().replace('.', '')
|
|
17
40
|
if (!extension) {
|
|
@@ -53,6 +76,30 @@ async function uploadFile({ token, projectId, language, filePath }) {
|
|
|
53
76
|
)
|
|
54
77
|
}
|
|
55
78
|
|
|
79
|
+
async function uploadFileWithRetry({ token, projectId, language, filePath }) {
|
|
80
|
+
let attempt = 0
|
|
81
|
+
while (true) {
|
|
82
|
+
attempt += 1
|
|
83
|
+
try {
|
|
84
|
+
await uploadFile({ token, projectId, language, filePath })
|
|
85
|
+
return
|
|
86
|
+
} catch (err) {
|
|
87
|
+
const errorCode = parsePoeditorError(err)
|
|
88
|
+
const isRetryable = errorCode && RETRYABLE_UPLOAD_ERROR_CODES.has(errorCode)
|
|
89
|
+
const retriesLeft = MAX_UPLOAD_RETRIES - attempt
|
|
90
|
+
if (!isRetryable || retriesLeft < 0) {
|
|
91
|
+
throw err
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const waitMs = MIN_UPLOAD_INTERVAL_MS
|
|
95
|
+
console.warn(
|
|
96
|
+
`[poeditor-upload] Received retryable POEditor error code ${errorCode}. Retrying in ${Math.ceil(waitMs / 1000)}s (${retriesLeft} retries left).`,
|
|
97
|
+
)
|
|
98
|
+
await sleep(waitMs)
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
56
103
|
async function main() {
|
|
57
104
|
const { flags } = parseFlags(process.argv.slice(2))
|
|
58
105
|
const cfg = loadPoeditorConfig(flags)
|
|
@@ -76,17 +123,26 @@ async function main() {
|
|
|
76
123
|
|
|
77
124
|
const uploads = cfg.uploadFiles && typeof cfg.uploadFiles === 'object' ? Object.entries(cfg.uploadFiles) : []
|
|
78
125
|
if (uploads.length > 0) {
|
|
126
|
+
let nextUploadAt = 0
|
|
79
127
|
for (const [language, file] of uploads) {
|
|
128
|
+
const now = Date.now()
|
|
129
|
+
const waitBeforeUploadMs = Math.max(0, nextUploadAt - now)
|
|
130
|
+
if (waitBeforeUploadMs > 0) {
|
|
131
|
+
console.log(`[poeditor-upload] Waiting ${Math.ceil(waitBeforeUploadMs / 1000)}s before next upload...`)
|
|
132
|
+
await sleep(waitBeforeUploadMs)
|
|
133
|
+
}
|
|
134
|
+
|
|
80
135
|
const filePath = resolvePathFromCwd(file)
|
|
81
|
-
await
|
|
136
|
+
await uploadFileWithRetry({ token, projectId, language, filePath })
|
|
82
137
|
console.log(`[poeditor-upload] Upload completed for ${language}: ${filePath}`)
|
|
138
|
+
nextUploadAt = Date.now() + MIN_UPLOAD_INTERVAL_MS
|
|
83
139
|
}
|
|
84
140
|
return
|
|
85
141
|
}
|
|
86
142
|
|
|
87
143
|
const language = cfg.defaultLanguage
|
|
88
144
|
const filePath = resolvePathFromCwd(cfg.uploadFile)
|
|
89
|
-
await
|
|
145
|
+
await uploadFileWithRetry({ token, projectId, language, filePath })
|
|
90
146
|
console.log(`[poeditor-upload] Upload completed for ${language}: ${filePath}`)
|
|
91
147
|
}
|
|
92
148
|
|
|
@@ -210,8 +210,6 @@ if (policyErrors.length > 0) {
|
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
fs.writeFileSync(policyPath, `${JSON.stringify(policy, null, 2)}\n`)
|
|
213
|
-
|
|
214
|
-
const fgDevkitRoot = path.resolve(scriptDir, '..')
|
|
215
213
|
syncScaffoldVueDepsFromPolicy({ fgDevkitRoot, policyPath })
|
|
216
214
|
|
|
217
215
|
console.log(`[refresh-policy] projectsRoot=${projectsRoot}`)
|
|
@@ -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)
|