fg-devkit 1.14.5 → 1.15.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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"toolchain": {
|
|
3
|
-
"packageManager": "pnpm@11.
|
|
3
|
+
"packageManager": "pnpm@11.25.0",
|
|
4
4
|
"node": {
|
|
5
5
|
"nvmrc": "22",
|
|
6
6
|
"engines": ">=22.13.0",
|
|
@@ -17,11 +17,8 @@
|
|
|
17
17
|
"@lexical/rich-text": "0.49.0",
|
|
18
18
|
"@lexical/link": "0.49.0",
|
|
19
19
|
"@piwikpro/vue-piwik-pro": "1.7.1",
|
|
20
|
-
"@sentry/
|
|
21
|
-
"@
|
|
22
|
-
"@sentry/vue": "10.70.0",
|
|
23
|
-
"@sentry/wasm": "10.70.0",
|
|
24
|
-
"@tanstack/vue-query": "5.101.4",
|
|
20
|
+
"@sentry/vue": "10.73.0",
|
|
21
|
+
"@tanstack/vue-query": "5.102.8",
|
|
25
22
|
"@types/leaflet": "1.9.22",
|
|
26
23
|
"@unhead/vue": "2.0.5",
|
|
27
24
|
"@vue-leaflet/vue-leaflet": "0.10.1",
|
|
@@ -32,8 +29,8 @@
|
|
|
32
29
|
"chart.js": "4.5.1",
|
|
33
30
|
"content-disposition-header": "0.6.0",
|
|
34
31
|
"date-fns": "4.4.0",
|
|
35
|
-
"element-plus": "2.14.
|
|
36
|
-
"fds-vue-core": "8.
|
|
32
|
+
"element-plus": "2.14.5",
|
|
33
|
+
"fds-vue-core": "8.6.4",
|
|
37
34
|
"imask": "7.6.1",
|
|
38
35
|
"leaflet": "1.9.4",
|
|
39
36
|
"lexical": "0.49.0",
|
|
@@ -41,14 +38,14 @@
|
|
|
41
38
|
"lodash-es": "4.18.1",
|
|
42
39
|
"markdown-it": "14.3.0",
|
|
43
40
|
"pinia": "3.0.4",
|
|
44
|
-
"playwright": "1.
|
|
41
|
+
"playwright": "1.63.0",
|
|
45
42
|
"quill": "2.0.3",
|
|
46
43
|
"randexp": "0.5.3",
|
|
47
44
|
"register-service-worker": "1.7.2",
|
|
48
|
-
"vega-embed": "7.
|
|
45
|
+
"vega-embed": "7.2.0",
|
|
49
46
|
"vega-lite": "6.4.3",
|
|
50
47
|
"vue-chartjs": "5.3.4",
|
|
51
|
-
"vue-i18n": "11.4.
|
|
48
|
+
"vue-i18n": "11.4.10",
|
|
52
49
|
"vue-quilly": "1.1.6",
|
|
53
50
|
"vue-router": "4.6.3",
|
|
54
51
|
"vue3-touch-keyboard": "1.3.9",
|
|
@@ -57,32 +54,32 @@
|
|
|
57
54
|
"yup": "1.7.1"
|
|
58
55
|
},
|
|
59
56
|
"devDependencies": {
|
|
60
|
-
"@chromatic-com/storybook": "5.3.
|
|
57
|
+
"@chromatic-com/storybook": "5.3.1",
|
|
61
58
|
"@eslint/js": "9.39.1",
|
|
62
59
|
"@intlify/unplugin-vue-i18n": "11.2.5",
|
|
63
|
-
"@playwright/test": "1.
|
|
64
|
-
"@storybook/addon-a11y": "10.
|
|
65
|
-
"@storybook/addon-docs": "10.
|
|
66
|
-
"@storybook/addon-vitest": "10.
|
|
67
|
-
"@storybook/vue3": "10.
|
|
68
|
-
"@storybook/vue3-vite": "10.
|
|
69
|
-
"@tanstack/vue-query-devtools": "6.1.
|
|
60
|
+
"@playwright/test": "1.63.0",
|
|
61
|
+
"@storybook/addon-a11y": "10.6.0",
|
|
62
|
+
"@storybook/addon-docs": "10.6.0",
|
|
63
|
+
"@storybook/addon-vitest": "10.6.0",
|
|
64
|
+
"@storybook/vue3": "10.6.0",
|
|
65
|
+
"@storybook/vue3-vite": "10.6.0",
|
|
66
|
+
"@tanstack/vue-query-devtools": "6.1.48",
|
|
70
67
|
"@tsconfig/node22": "22.0.6",
|
|
71
68
|
"@types/lodash-es": "4.17.12",
|
|
72
69
|
"@types/node": "22.16.5",
|
|
73
70
|
"@vitest/browser": "4.1.10",
|
|
74
|
-
"@vue/compiler-dom": "3.5.
|
|
71
|
+
"@vue/compiler-dom": "3.5.42",
|
|
75
72
|
"@vue/eslint-config-standard": "8.0.1",
|
|
76
|
-
"@vue/server-renderer": "3.5.
|
|
77
|
-
"@vue/test-utils": "2.
|
|
73
|
+
"@vue/server-renderer": "3.5.42",
|
|
74
|
+
"@vue/test-utils": "2.5.0",
|
|
78
75
|
"arg": "5.0.2",
|
|
79
76
|
"babel-eslint": "10.1.0",
|
|
80
|
-
"eslint-plugin-storybook": "10.
|
|
77
|
+
"eslint-plugin-storybook": "10.6.0",
|
|
81
78
|
"globals": "15.11.0",
|
|
82
79
|
"jsdom": "26.1.0",
|
|
83
|
-
"sass": "1.
|
|
84
|
-
"storybook": "10.
|
|
85
|
-
"tsx": "4.23.
|
|
80
|
+
"sass": "1.104.0",
|
|
81
|
+
"storybook": "10.6.0",
|
|
82
|
+
"tsx": "4.23.13",
|
|
86
83
|
"vega": "6.4.0",
|
|
87
84
|
"vite-plugin-dts": "4.5.4",
|
|
88
85
|
"vite-plugin-vue-devtools": "8.2.1",
|
|
@@ -93,11 +90,11 @@
|
|
|
93
90
|
"managedAnywhere": {
|
|
94
91
|
"@tailwindcss/vite": "4.3.3",
|
|
95
92
|
"@vitejs/plugin-vue": "6.0.8",
|
|
96
|
-
"axios": "1.
|
|
93
|
+
"axios": "1.20.0",
|
|
97
94
|
"dotenv": "16.4.5",
|
|
98
|
-
"qrcode.vue": "3.
|
|
95
|
+
"qrcode.vue": "3.11.0",
|
|
99
96
|
"tailwindcss": "4.3.3",
|
|
100
97
|
"vite": "7.3.5",
|
|
101
|
-
"vue": "3.5.
|
|
98
|
+
"vue": "3.5.42"
|
|
102
99
|
}
|
|
103
100
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fg-devkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.1",
|
|
4
4
|
"description": "Shared configs, scripts, and DX tooling for Vue / TypeScript frontend repos",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -102,32 +102,32 @@
|
|
|
102
102
|
},
|
|
103
103
|
"dependencies": {
|
|
104
104
|
"@inquirer/checkbox": "4.3.2",
|
|
105
|
-
"@inquirer/confirm": "6.
|
|
106
|
-
"@inquirer/input": "5.1.
|
|
107
|
-
"@inquirer/select": "5.2.
|
|
105
|
+
"@inquirer/confirm": "6.3.1",
|
|
106
|
+
"@inquirer/input": "5.1.5",
|
|
107
|
+
"@inquirer/select": "5.2.4",
|
|
108
108
|
"@intlify/eslint-plugin-vue-i18n": "4.5.1",
|
|
109
|
-
"@typescript-eslint/eslint-plugin": "8.
|
|
110
|
-
"@typescript-eslint/parser": "8.
|
|
109
|
+
"@typescript-eslint/eslint-plugin": "8.69.0",
|
|
110
|
+
"@typescript-eslint/parser": "8.69.0",
|
|
111
111
|
"@vitest/eslint-plugin": "1.6.27",
|
|
112
112
|
"@vue/eslint-config-prettier": "10.2.0",
|
|
113
113
|
"@vue/eslint-config-typescript": "14.9.0",
|
|
114
114
|
"@vue/tsconfig": "0.9.1",
|
|
115
|
-
"eslint": "10.
|
|
115
|
+
"eslint": "10.10.0",
|
|
116
116
|
"eslint-plugin-prettier": "5.5.6",
|
|
117
|
-
"eslint-plugin-vue": "10.
|
|
117
|
+
"eslint-plugin-vue": "10.11.0",
|
|
118
118
|
"fallow": "2.101.0",
|
|
119
119
|
"git-cliff": "2.13.1",
|
|
120
|
-
"lefthook": "2.1.
|
|
120
|
+
"lefthook": "2.1.12",
|
|
121
121
|
"npm-check-updates": "22.2.7",
|
|
122
122
|
"prettier": "3.9.6",
|
|
123
|
-
"tsx": "4.23.
|
|
123
|
+
"tsx": "4.23.13",
|
|
124
124
|
"typescript": "5.9.3",
|
|
125
125
|
"vue-eslint-parser": "10.4.1",
|
|
126
|
-
"vue-tsc": "3.3.
|
|
126
|
+
"vue-tsc": "3.3.11"
|
|
127
127
|
},
|
|
128
128
|
"devDependencies": {
|
|
129
|
-
"cz-git": "1.
|
|
130
|
-
"czg": "1.
|
|
129
|
+
"cz-git": "1.14.0",
|
|
130
|
+
"czg": "1.14.0"
|
|
131
131
|
},
|
|
132
132
|
"scripts": {
|
|
133
133
|
"maintainer-ui": "pnpm --dir electron/maintainer-ui start",
|
|
@@ -16,29 +16,29 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@tailwindcss/vite": "4.3.3",
|
|
19
|
-
"@tanstack/vue-query": "5.
|
|
20
|
-
"axios": "1.
|
|
19
|
+
"@tanstack/vue-query": "5.102.8",
|
|
20
|
+
"axios": "1.20.0",
|
|
21
21
|
"content-disposition-header": "0.6.0",
|
|
22
22
|
"date-fns": "4.4.0",
|
|
23
23
|
"dotenv": "16.4.5",
|
|
24
|
-
"fds-vue-core": "8.
|
|
24
|
+
"fds-vue-core": "8.6.4",
|
|
25
25
|
"pinia": "3.0.4",
|
|
26
|
-
"qrcode.vue": "3.
|
|
27
|
-
"vue": "3.5.
|
|
28
|
-
"vue-i18n": "11.4.
|
|
26
|
+
"qrcode.vue": "3.11.0",
|
|
27
|
+
"vue": "3.5.42",
|
|
28
|
+
"vue-i18n": "11.4.10",
|
|
29
29
|
"vue-router": "4.6.3"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@intlify/unplugin-vue-i18n": "11.2.5",
|
|
33
|
-
"@tanstack/vue-query-devtools": "6.1.
|
|
33
|
+
"@tanstack/vue-query-devtools": "6.1.48",
|
|
34
34
|
"@types/node": "22.16.5",
|
|
35
35
|
"@vitejs/plugin-vue": "6.0.8",
|
|
36
|
-
"fg-devkit": "1.
|
|
36
|
+
"fg-devkit": "1.15.1",
|
|
37
37
|
"tailwindcss": "4.3.3",
|
|
38
|
-
"tsx": "4.23.
|
|
38
|
+
"tsx": "4.23.13",
|
|
39
39
|
"vite": "7.3.5"
|
|
40
40
|
},
|
|
41
|
-
"packageManager": "pnpm@11.
|
|
41
|
+
"packageManager": "pnpm@11.25.0",
|
|
42
42
|
"engines": {
|
|
43
43
|
"node": ">=22.13.0"
|
|
44
44
|
}
|
package/scripts/fg-devkit.mjs
CHANGED
|
@@ -559,7 +559,7 @@ Commands:
|
|
|
559
559
|
fallow [fallow-args...] Run Fallow using fg-devkit bundled package
|
|
560
560
|
dead-code [fallow-args...] Run Fallow dead code analysis (shortcut for: fallow dead-code)
|
|
561
561
|
poeditor-download [args...] Download locale files via PoEditor (reads poeditor/.poeditor.json by default)
|
|
562
|
-
poeditor-upload [args...] Upload locale file via PoEditor (reads poeditor/.poeditor.json by default)
|
|
562
|
+
poeditor-upload [args...] Upload locale file via PoEditor (reads poeditor/.poeditor.json by default; --sync-terms deletes missing terms)
|
|
563
563
|
scaffold-vue <target-dir> [--name …] [--slug …] [--force] …
|
|
564
564
|
Copy the bundled Vue scaffold into target-dir (see script header)
|
|
565
565
|
sync-scaffold-vue-deps [policy-file]
|
|
@@ -589,11 +589,14 @@ function isFgDevkitMaintainerContext() {
|
|
|
589
589
|
|
|
590
590
|
async function runInteractiveMenu() {
|
|
591
591
|
let selectPrompt
|
|
592
|
+
let confirmPrompt
|
|
592
593
|
try {
|
|
593
594
|
const inquirerSelect = await import('@inquirer/select')
|
|
595
|
+
const inquirerConfirm = await import('@inquirer/confirm')
|
|
594
596
|
selectPrompt = inquirerSelect.default
|
|
597
|
+
confirmPrompt = inquirerConfirm.default
|
|
595
598
|
} catch {
|
|
596
|
-
console.error('[fg-devkit] Interactive menu requires @inquirer/select but
|
|
599
|
+
console.error('[fg-devkit] Interactive menu requires @inquirer/select and @inquirer/confirm but they are not available.')
|
|
597
600
|
console.error('[fg-devkit] Run pnpm install in your project and try again.')
|
|
598
601
|
return 1
|
|
599
602
|
}
|
|
@@ -769,7 +772,34 @@ async function runInteractiveMenu() {
|
|
|
769
772
|
loop: false,
|
|
770
773
|
})
|
|
771
774
|
if (choice === 'cancel') continue
|
|
772
|
-
|
|
775
|
+
if (choice === 'download') {
|
|
776
|
+
return runSelectedAction(() => runNode('poeditor-download.mjs'))
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
const uploadMode = await selectPrompt({
|
|
780
|
+
message: 'Upload mode',
|
|
781
|
+
choices: [
|
|
782
|
+
{ name: 'Upload (keep terms missing from file)', value: 'upload' },
|
|
783
|
+
{
|
|
784
|
+
name: 'Upload + sync terms (delete terms missing from file)',
|
|
785
|
+
value: 'upload-sync',
|
|
786
|
+
},
|
|
787
|
+
{ name: 'Cancel', value: 'cancel' },
|
|
788
|
+
],
|
|
789
|
+
default: 'upload',
|
|
790
|
+
loop: false,
|
|
791
|
+
})
|
|
792
|
+
if (uploadMode === 'cancel') continue
|
|
793
|
+
if (uploadMode === 'upload-sync') {
|
|
794
|
+
const confirmed = await confirmPrompt({
|
|
795
|
+
message:
|
|
796
|
+
'This is a destructive POEditor action: terms not present in the uploaded file will be permanently deleted from the project (including all language translations). Continue?',
|
|
797
|
+
default: false,
|
|
798
|
+
})
|
|
799
|
+
if (!confirmed) continue
|
|
800
|
+
}
|
|
801
|
+
const uploadArgs = uploadMode === 'upload-sync' ? ['--sync-terms'] : []
|
|
802
|
+
return runSelectedAction(() => runNode('poeditor-upload.mjs', uploadArgs))
|
|
773
803
|
}
|
|
774
804
|
|
|
775
805
|
if (group === 'dependency-policy') {
|
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
6
|
* pnpm exec fg-devkit poeditor-upload [--config ./poeditor/.poeditor.json] [--project-id 123]
|
|
7
|
-
* [--language sv] [--file ./src/lang/sv.json] [--api-token xxx]
|
|
7
|
+
* [--language sv] [--file ./src/lang/sv.json] [--api-token xxx] [--sync-terms]
|
|
8
|
+
*
|
|
9
|
+
* --sync-terms: Pass sync_terms=1 to PoEditor so terms missing from the uploaded file
|
|
10
|
+
* are deleted from the project (destructive; use with care).
|
|
8
11
|
*/
|
|
9
12
|
|
|
10
13
|
import fs from 'node:fs'
|
|
@@ -22,6 +25,12 @@ function sleep(ms) {
|
|
|
22
25
|
})
|
|
23
26
|
}
|
|
24
27
|
|
|
28
|
+
function isTruthyFlag(value) {
|
|
29
|
+
if (value === undefined) return false
|
|
30
|
+
const normalized = String(value).trim().toLowerCase()
|
|
31
|
+
return normalized === 'true' || normalized === '1' || normalized === 'yes'
|
|
32
|
+
}
|
|
33
|
+
|
|
25
34
|
function parsePoeditorError(err) {
|
|
26
35
|
const message = err instanceof Error ? err.message : String(err)
|
|
27
36
|
const match = message.match(/Upload failed:\s*(\{.*\})$/)
|
|
@@ -46,7 +55,7 @@ function getUploadType(filePath) {
|
|
|
46
55
|
return extension
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
async function uploadFile({ token, projectId, language, filePath }) {
|
|
58
|
+
async function uploadFile({ token, projectId, language, filePath, syncTerms = false }) {
|
|
50
59
|
const fileBuffer = fs.readFileSync(filePath)
|
|
51
60
|
const fileName = path.basename(filePath)
|
|
52
61
|
const uploadType = getUploadType(filePath)
|
|
@@ -56,6 +65,7 @@ async function uploadFile({ token, projectId, language, filePath }) {
|
|
|
56
65
|
form.append('updating', 'terms_translations')
|
|
57
66
|
form.append('language', language)
|
|
58
67
|
form.append('overwrite', '1')
|
|
68
|
+
form.append('sync_terms', syncTerms ? '1' : '0')
|
|
59
69
|
form.append('type', uploadType)
|
|
60
70
|
form.append('file', new Blob([fileBuffer]), fileName)
|
|
61
71
|
|
|
@@ -70,18 +80,20 @@ async function uploadFile({ token, projectId, language, filePath }) {
|
|
|
70
80
|
if (data?.response?.status !== 'success') {
|
|
71
81
|
throw new Error(`Upload failed: ${JSON.stringify(data)}`)
|
|
72
82
|
}
|
|
83
|
+
const terms = data?.result?.terms
|
|
73
84
|
const translations = data?.result?.translations
|
|
85
|
+
const syncNote = syncTerms ? `, terms deleted: ${terms?.deleted ?? 0}` : ''
|
|
74
86
|
console.log(
|
|
75
|
-
`[poeditor-upload] Upload complete for "${language}" (parsed: ${translations?.parsed ?? 0}, updated: ${translations?.updated ?? 0}, added: ${translations?.added ?? 0})`,
|
|
87
|
+
`[poeditor-upload] Upload complete for "${language}" (parsed: ${translations?.parsed ?? 0}, updated: ${translations?.updated ?? 0}, added: ${translations?.added ?? 0}${syncNote})`,
|
|
76
88
|
)
|
|
77
89
|
}
|
|
78
90
|
|
|
79
|
-
async function uploadFileWithRetry({ token, projectId, language, filePath }) {
|
|
91
|
+
async function uploadFileWithRetry({ token, projectId, language, filePath, syncTerms = false }) {
|
|
80
92
|
let attempt = 0
|
|
81
93
|
while (true) {
|
|
82
94
|
attempt += 1
|
|
83
95
|
try {
|
|
84
|
-
await uploadFile({ token, projectId, language, filePath })
|
|
96
|
+
await uploadFile({ token, projectId, language, filePath, syncTerms })
|
|
85
97
|
return
|
|
86
98
|
} catch (err) {
|
|
87
99
|
const errorCode = parsePoeditorError(err)
|
|
@@ -111,20 +123,32 @@ async function main() {
|
|
|
111
123
|
}
|
|
112
124
|
|
|
113
125
|
const projectId = getFlagValue(flags, 'project-id', cfg.projectId)
|
|
126
|
+
const syncTerms = isTruthyFlag(getFlagValue(flags, 'sync-terms'))
|
|
127
|
+
if (syncTerms) {
|
|
128
|
+
console.warn(
|
|
129
|
+
'[poeditor-upload] --sync-terms enabled: terms not present in the uploaded file will be deleted from PoEditor.',
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
114
133
|
const hasExplicitLanguage = flags.has('language')
|
|
115
134
|
const hasExplicitFile = flags.has('file')
|
|
116
135
|
if (hasExplicitLanguage || hasExplicitFile) {
|
|
117
136
|
const language = getFlagValue(flags, 'language', cfg.defaultLanguage)
|
|
118
137
|
const filePath = resolvePathFromCwd(getFlagValue(flags, 'file', cfg.uploadFile))
|
|
119
|
-
await uploadFile({ token, projectId, language, filePath })
|
|
138
|
+
await uploadFile({ token, projectId, language, filePath, syncTerms })
|
|
120
139
|
console.log(`[poeditor-upload] Upload completed for ${language}: ${filePath}`)
|
|
121
140
|
return
|
|
122
141
|
}
|
|
123
142
|
|
|
124
143
|
const uploads = cfg.uploadFiles && typeof cfg.uploadFiles === 'object' ? Object.entries(cfg.uploadFiles) : []
|
|
125
144
|
if (uploads.length > 0) {
|
|
145
|
+
if (syncTerms && uploads.length > 1) {
|
|
146
|
+
console.warn(
|
|
147
|
+
'[poeditor-upload] --sync-terms with multiple uploadFiles: syncing only on the first file to avoid deleting terms present in other language files.',
|
|
148
|
+
)
|
|
149
|
+
}
|
|
126
150
|
let nextUploadAt = 0
|
|
127
|
-
for (const [language, file] of uploads) {
|
|
151
|
+
for (const [index, [language, file]] of uploads.entries()) {
|
|
128
152
|
const now = Date.now()
|
|
129
153
|
const waitBeforeUploadMs = Math.max(0, nextUploadAt - now)
|
|
130
154
|
if (waitBeforeUploadMs > 0) {
|
|
@@ -133,7 +157,8 @@ async function main() {
|
|
|
133
157
|
}
|
|
134
158
|
|
|
135
159
|
const filePath = resolvePathFromCwd(file)
|
|
136
|
-
|
|
160
|
+
const shouldSyncTerms = syncTerms && index === 0
|
|
161
|
+
await uploadFileWithRetry({ token, projectId, language, filePath, syncTerms: shouldSyncTerms })
|
|
137
162
|
console.log(`[poeditor-upload] Upload completed for ${language}: ${filePath}`)
|
|
138
163
|
nextUploadAt = Date.now() + MIN_UPLOAD_INTERVAL_MS
|
|
139
164
|
}
|
|
@@ -142,7 +167,7 @@ async function main() {
|
|
|
142
167
|
|
|
143
168
|
const language = cfg.defaultLanguage
|
|
144
169
|
const filePath = resolvePathFromCwd(cfg.uploadFile)
|
|
145
|
-
await uploadFileWithRetry({ token, projectId, language, filePath })
|
|
170
|
+
await uploadFileWithRetry({ token, projectId, language, filePath, syncTerms })
|
|
146
171
|
console.log(`[poeditor-upload] Upload completed for ${language}: ${filePath}`)
|
|
147
172
|
}
|
|
148
173
|
|