i18n-dashboard 0.12.1 → 0.13.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.
- package/README.md +47 -727
- package/bin/cli.mjs +13 -9
- package/nuxt.config.ts +34 -2
- package/package.json +1 -1
- package/src/components/GitRepoManager.vue +4 -4
- package/src/components/ScanModal.vue +3 -3
- package/src/components/TranslationRow.vue +1 -1
- package/src/components/dashboard/WidgetConfigModal.vue +6 -5
- package/src/components/dashboard/WidgetGrid.vue +2 -2
- package/src/components/dashboard/WidgetPicker.vue +6 -5
- package/src/components/dashboard/widgets/ActivityWidget.vue +4 -3
- package/src/components/dashboard/widgets/LanguagesCoverageWidget.vue +4 -3
- package/src/components/dashboard/widgets/ProjectsWidget.vue +2 -2
- package/src/components/dashboard/widgets/ReviewWidget.vue +5 -4
- package/src/components/dashboard/widgets/StatWidget.vue +5 -4
- package/src/composables/useAuth.ts +2 -10
- package/src/composables/useDashboard.ts +7 -7
- package/src/composables/useKeys.ts +3 -3
- package/src/composables/useLanguages.ts +6 -6
- package/src/composables/useProfile.ts +1 -1
- package/src/composables/useProject.ts +8 -23
- package/src/composables/useReview.ts +5 -12
- package/src/composables/useSettings.ts +2 -2
- package/src/composables/useStats.ts +2 -2
- package/src/composables/useUsers.ts +3 -3
- package/src/composables/useWidgetData.ts +2 -2
- package/src/consts/commons.const.ts +20 -5
- package/src/consts/dashboard.const.ts +6 -5
- package/src/consts/languages.const.ts +2 -2
- package/src/consts/translation-job.const.ts +2 -0
- package/src/enums/translation-job.enum.ts +5 -0
- package/src/interfaces/auth.interface.ts +8 -0
- package/src/interfaces/commons.interface.ts +9 -9
- package/src/interfaces/dashboard.interface.ts +12 -0
- package/src/interfaces/job.interface.ts +1 -1
- package/src/interfaces/key.interface.ts +8 -8
- package/src/interfaces/languages.interface.ts +3 -3
- package/src/{server/interfaces → interfaces}/profile.interface.ts +9 -9
- package/src/{server/interfaces → interfaces}/project-config.interface.ts +1 -1
- package/src/interfaces/project-snapshot.interface.ts +26 -0
- package/src/interfaces/project.interface.ts +18 -3
- package/src/interfaces/review.interface.ts +7 -0
- package/src/interfaces/scan.interface.ts +2 -2
- package/src/{server/interfaces → interfaces}/scanner.interface.ts +4 -4
- package/src/interfaces/settings.interface.ts +1 -1
- package/src/interfaces/stat.interface.ts +5 -5
- package/src/{server/interfaces → interfaces}/translation-job.interface.ts +3 -3
- package/src/interfaces/translation.interface.ts +2 -2
- package/src/interfaces/user.interface.ts +3 -3
- package/src/pages/projects/[id]/review.vue +1 -1
- package/src/pages/projects/[id]/translations/index.vue +1 -1
- package/src/pages/projects/[id]/users.vue +4 -4
- package/src/server/api/auth/login.post.ts +1 -1
- package/src/server/api/auth/logout.post.ts +1 -1
- package/src/server/api/auth/me.get.ts +1 -1
- package/src/server/api/auth/me.put.ts +1 -1
- package/src/server/api/auth/password.put.ts +1 -1
- package/src/server/api/auth/refresh.post.ts +1 -1
- package/src/server/api/auth/status.get.ts +1 -1
- package/src/server/api/config.get.ts +1 -1
- package/src/server/api/dashboard/layout.get.ts +1 -1
- package/src/server/api/dashboard/layout.post.ts +1 -1
- package/src/server/api/db-config.post.ts +4 -1
- package/src/server/api/export.get.ts +1 -1
- package/src/server/api/fs/browse.get.ts +15 -1
- package/src/server/api/languages/index.post.ts +1 -1
- package/src/server/api/onboarding.post.ts +1 -1
- package/src/server/api/profile.get.ts +2 -2
- package/src/server/api/project-snapshot.post.ts +2 -28
- package/src/server/api/projects/detect.post.ts +1 -1
- package/src/server/api/scan.post.ts +15 -5
- package/src/server/api/setup.post.ts +1 -1
- package/src/server/api/stats/global.get.ts +1 -1
- package/src/server/api/sync.post.ts +12 -4
- package/src/server/api/translations/bulk-status.post.ts +12 -4
- package/src/server/api/translations/index.post.ts +1 -1
- package/src/server/api/translations/job/[id].get.ts +1 -1
- package/src/server/api/translations/status.post.ts +9 -2
- package/src/server/api/translations/translate-all.post.ts +1 -1
- package/src/server/api/users/[id]/profile.get.ts +3 -3
- package/src/server/api/users/[id]/roles.put.ts +1 -1
- package/src/server/api/users/[id].delete.ts +1 -1
- package/src/server/api/users/[id].put.ts +1 -1
- package/src/server/api/users/index.get.ts +1 -1
- package/src/server/api/users/index.post.ts +9 -4
- package/src/server/consts/commons.const.ts +6 -11
- package/src/server/db/index.ts +17 -4
- package/src/server/middleware/auth.ts +19 -3
- package/src/server/routes/locale/[lang].get.ts +7 -4
- package/src/server/utils/auth.util.ts +10 -10
- package/src/server/utils/auto-translate.util.ts +1 -1
- package/src/server/utils/project-config.util.ts +3 -3
- package/src/server/utils/{scanner.uti.ts → scanner.util.ts} +13 -13
- package/src/server/utils/translation-job.util.ts +14 -13
- package/src/services/auth.service.ts +10 -10
- package/src/services/base.service.ts +13 -13
- package/src/services/job.service.ts +6 -6
- package/src/services/key.service.ts +10 -10
- package/src/services/language.service.ts +8 -8
- package/src/services/profile.service.ts +8 -8
- package/src/services/project.service.ts +11 -11
- package/src/services/scan.service.ts +8 -8
- package/src/services/settings.service.ts +5 -5
- package/src/services/stats.service.ts +6 -6
- package/src/services/translation.service.ts +6 -6
- package/src/services/user.service.ts +10 -10
- package/src/types/auth.type.ts +3 -0
- package/src/types/commons.type.ts +1 -1
- package/src/types/dashboard.type.ts +5 -15
- package/src/consts/commons.const.js +0 -6
- package/src/server/consts/translation-job.const.ts +0 -8
- package/src/server/types/auth.type.ts +0 -3
- /package/src/{server/consts → consts}/auto-translate.const.ts +0 -0
- /package/src/{server/consts → consts}/scanner.const.ts +0 -0
- /package/src/{server/enums → enums}/auth.enum.ts +0 -0
- /package/src/{server/enums → enums}/translation.enum.ts +0 -0
- /package/src/{server/utils → utils}/lang-api.util.ts +0 -0
package/README.md
CHANGED
|
@@ -1,779 +1,99 @@
|
|
|
1
|
-
# i18n
|
|
1
|
+
# Vue i18n Dashboard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Stop editing JSON files manually.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Manage your Vue i18n translations in a real-time dashboard — with two possible workflows:
|
|
6
|
+
- Local (per project)
|
|
7
|
+
- Server (multi-project platform)
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
### Core
|
|
14
|
-
- **Multi-project** — manage multiple Vue.js projects from one dashboard, each with its own languages, keys, and settings
|
|
15
|
-
- **Translation editor** — inline editing per language, keyboard shortcuts (`Ctrl+Enter` to save, `Esc` to cancel)
|
|
16
|
-
- **Plural forms** — dedicated plural editor supporting 2-form (EN/DE), 3-form (FR/ES), 4-form (Slavic), or custom rules
|
|
17
|
-
- **Key linking** — insert `@:key` linked references with optional modifiers (`.lower`, `.upper`, `.capitalize`) via a searchable modal picker
|
|
18
|
-
- **Escape helpers** — quick-insert toolbar for vue-i18n special characters (`{'@'}`, `{'{'}`, `\\{`, etc.)
|
|
19
|
-
- **Translation history** — every change (manual, sync, auto-translate) is tracked; restore any previous version
|
|
20
|
-
- **Inline auto-translate** — Google Translate per key (free tier, no API key required)
|
|
21
|
-
- **Batch auto-translate** — translate all missing keys for an entire language at once
|
|
22
|
-
- **Review workflow** — `Draft → Reviewed → Approved` status pipeline with role-based access control
|
|
23
|
-
- **Dashboard widgets** — customizable overview: coverage, total keys, unused keys, recent activity, per-language progress
|
|
24
|
-
|
|
25
|
-
### Languages
|
|
26
|
-
- **BCP 47 support** — full regional codes: `fr-CA`, `en-GB`, `pt-BR`, `zh-CN`, `sr-Latn`, etc. (170+ locales)
|
|
27
|
-
- **Fallback chains** — configure explicit fallbacks per language (`fr-CA → fr → en`); automatic BCP 47 parent resolution
|
|
28
|
-
- **Auto-detect** — scan or sync automatically detects locale files and creates the corresponding languages
|
|
29
|
-
- **Default language** — designate one language as the source for auto-translate
|
|
30
|
-
|
|
31
|
-
### Scan & Sync
|
|
32
|
-
- **Source scan (local)** — browse your file system with the built-in folder picker, detect all `$t()`, `t()`, `<i18n-t>`, `v-t`, and `<i18n>` block usages across `.vue`, `.ts`, `.js` files
|
|
33
|
-
- **Source scan (git)** — provide a git repository URL (+ optional branch and access token); the dashboard clones the repo, scans source files, and imports locale files in one step
|
|
34
|
-
- **Sync (local)** — import existing `.json` locale files from a local path into the database
|
|
35
|
-
- **Sync (git)** — clone the configured git repository and import locale JSON files; only fills missing or empty translations — never overwrites existing values
|
|
36
|
-
- **Unused key detection** — keys not found in source files are automatically flagged
|
|
37
|
-
- **Conflict-safe import** — sync and scan never overwrite a translation that already has a value in the database
|
|
38
|
-
|
|
39
|
-
### Advanced Formats
|
|
40
|
-
*(enable per project in Settings)*
|
|
41
|
-
- **Number formats** — configure `$n(value, 'currency')` presets using `Intl.NumberFormat` with live preview
|
|
42
|
-
- **Datetime formats** — configure `$d(date, 'short')` presets using `Intl.DateTimeFormat` with live preview
|
|
43
|
-
- **Custom modifiers** — define `@.modifier:key` transform functions with a built-in test runner
|
|
44
|
-
- **Snippet generator** — generates a ready-to-paste `createI18n()` configuration block
|
|
45
|
-
|
|
46
|
-
### Projects
|
|
47
|
-
- **3-step creation wizard** — Source → Info → Languages: add a local path or git repo, auto-detect project name, locales folder and existing languages, then pick languages with the built-in BCP 47 picker
|
|
48
|
-
- **Auto-detect on creation** — reads `package.json` for the project name and scans the locale folder to pre-fill languages; works with both local paths and git repos
|
|
49
|
-
- **Auto-scan on creation** — a scan is automatically triggered after project creation so keys are immediately available
|
|
50
|
-
- **Git repository per project** — configure a git URL, branch, and optional access token; used for scan and sync operations without requiring a local clone
|
|
51
|
-
- **Inline settings** — edit project name, root path, git repo, locales folder, key separator, color, and description directly from the project settings page
|
|
52
|
-
- **Folder browser** — navigate your file system visually to pick the project root path
|
|
53
|
-
- **Project snapshot** — export a complete backup (config + languages + all keys + translations) as a single JSON file, import it on any other instance (merge or replace mode)
|
|
54
|
-
|
|
55
|
-
### Users & Authentication
|
|
56
|
-
- **Role-based access** — `Super Admin`, `Admin`, `Moderator`, `Translator` — per-project assignments
|
|
57
|
-
- **User search when adding to a project** — search existing users by name or email, select one and choose their role directly; or switch to the creation form for a brand new account
|
|
58
|
-
- **User activity profile** — view translation statistics per user with a configurable time period (last 24h, 7d, 30d, 1 year, or since account creation)
|
|
59
|
-
- **Onboarding wizard** — guided setup on first launch
|
|
60
|
-
- **Multi-language UI** — the dashboard interface itself is translatable
|
|
61
|
-
|
|
62
|
-
### Technical
|
|
63
|
-
- **Multi-database** — SQLite (default, zero config), PostgreSQL, MySQL/MariaDB
|
|
64
|
-
- **Auto-migration** — schema is created and updated automatically on startup
|
|
65
|
-
- **REST API** — full API for all operations, consume locale JSON from your Vue app
|
|
66
|
-
- **CORS auto-detection** — multiple app URLs per project; all are checked for CORS on `/locale/[lang].json`
|
|
67
|
-
- **Global loading overlay** — a full-page loading screen prevents interaction before data is ready, including on direct page load (F5) for any route
|
|
68
|
-
- **Dark mode** — system preference + manual toggle
|
|
69
|
-
- **Cypress E2E test suite** — full test coverage across all pages (auth, dashboard, projects, translations, languages, users, review, settings); CI-ready with GitHub Actions
|
|
70
|
-
- **GitHub Actions CI** — E2E tests run automatically on every push to `develop` and `main`; Cypress screenshots uploaded as artifacts on failure
|
|
71
|
-
- **Vitest unit test suite** — 344 unit tests covering all composables, services, and server utilities; runs in under 2 minutes with zero infrastructure required
|
|
72
|
-
- **Dual CI pipelines** — unit tests (`unit.yml`) and E2E tests (`e2e.yml`) run in parallel on every push; any regression blocks the pipeline
|
|
73
|
-
- **`src/` layout** — all source files live under `src/` (components, composables, pages, server, services, etc.) for a clean project root
|
|
74
|
-
---
|
|
11
|
+
## 🚨 The Problem
|
|
75
12
|
|
|
76
|
-
|
|
13
|
+
Working with vue-i18n can be painful:
|
|
77
14
|
|
|
78
|
-
-
|
|
79
|
-
-
|
|
15
|
+
- Editing JSON files manually
|
|
16
|
+
- No real-time feedback
|
|
17
|
+
- Difficult collaboration
|
|
18
|
+
- No centralized management across projects
|
|
80
19
|
|
|
81
20
|
---
|
|
82
21
|
|
|
83
|
-
##
|
|
22
|
+
## 💥 The Solution
|
|
84
23
|
|
|
85
|
-
|
|
24
|
+
Vue i18n Dashboard gives you:
|
|
86
25
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
```
|
|
26
|
+
- A local tool for your project
|
|
27
|
+
- OR a full translation management platform
|
|
90
28
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
npm install -g i18n-dashboard
|
|
95
|
-
```
|
|
29
|
+
No migration. No vendor lock-in. Works with vue-i18n.
|
|
96
30
|
|
|
97
31
|
---
|
|
98
32
|
|
|
99
|
-
## Quick Start
|
|
100
|
-
|
|
101
|
-
### 1 — Initialize
|
|
102
|
-
|
|
103
|
-
Run the interactive setup wizard from your project root:
|
|
33
|
+
## ⚡ Quick Start
|
|
104
34
|
|
|
105
35
|
```bash
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
This creates an `i18n-dashboard.config.js` file at the root of your project.
|
|
110
|
-
|
|
111
|
-
### 2 — Start
|
|
36
|
+
npm install i18n-dashboard --save-dev
|
|
37
|
+
or
|
|
38
|
+
npm install -g i18n-dashboard --save-dev
|
|
112
39
|
|
|
113
|
-
|
|
40
|
+
npx i18n-dashboard init
|
|
114
41
|
npx i18n-dashboard start
|
|
115
42
|
```
|
|
116
43
|
|
|
117
|
-
Open
|
|
118
|
-
|
|
119
|
-
The onboarding wizard will guide you through:
|
|
120
|
-
1. Creating an administrator account
|
|
121
|
-
2. Selecting the dashboard UI language
|
|
122
|
-
3. Configuring your first project
|
|
123
|
-
|
|
124
|
-
### 3 — Import existing locale files (optional)
|
|
125
|
-
|
|
126
|
-
If you already have `.json` locale files, import them into the database:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
npx i18n-dashboard sync
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
> The dashboard must be running for this command to work.
|
|
133
|
-
|
|
134
|
-
### 4 — Use the API in your Vue app
|
|
135
|
-
|
|
136
|
-
```js
|
|
137
|
-
// src/i18n.js
|
|
138
|
-
import { createI18n } from 'vue-i18n'
|
|
139
|
-
|
|
140
|
-
export const i18n = createI18n({
|
|
141
|
-
locale: 'en',
|
|
142
|
-
fallbackLocale: 'en',
|
|
143
|
-
messages: {
|
|
144
|
-
en: await fetch('http://localhost:3333/locale/en.json').then(r => r.json()),
|
|
145
|
-
fr: await fetch('http://localhost:3333/locale/fr.json').then(r => r.json()),
|
|
146
|
-
},
|
|
147
|
-
})
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
### 5 — Add a script to your package.json
|
|
151
|
-
|
|
152
|
-
```json
|
|
153
|
-
{
|
|
154
|
-
"scripts": {
|
|
155
|
-
"dev": "vite",
|
|
156
|
-
"i18n": "i18n-dashboard start"
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
```
|
|
44
|
+
👉 Open http://localhost:3333
|
|
160
45
|
|
|
161
46
|
---
|
|
162
47
|
|
|
163
|
-
##
|
|
164
|
-
|
|
165
|
-
### i18n-dashboard.config.js
|
|
166
|
-
|
|
167
|
-
```js
|
|
168
|
-
// i18n-dashboard.config.js
|
|
169
|
-
export default {
|
|
170
|
-
// Port the dashboard will run on
|
|
171
|
-
port: 3333,
|
|
172
|
-
|
|
173
|
-
// Key separator for nested keys ('home.title' uses '.')
|
|
174
|
-
keySeparator: '.',
|
|
175
|
-
|
|
176
|
-
// URL path pattern for serving locale JSON files
|
|
177
|
-
apiPath: '/locale/[lang].json',
|
|
48
|
+
## 🧠 Two Ways to Use It
|
|
178
49
|
|
|
179
|
-
|
|
180
|
-
projectRoot: './',
|
|
50
|
+
### 🟢 Local Mode
|
|
181
51
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
client: 'better-sqlite3',
|
|
52
|
+
- Run inside your project
|
|
53
|
+
- Sync keys from your code
|
|
54
|
+
- Export JSON files
|
|
186
55
|
|
|
187
|
-
|
|
188
|
-
connection: './i18n-dashboard.db',
|
|
189
|
-
|
|
190
|
-
// PostgreSQL / MySQL: use a connection object instead:
|
|
191
|
-
// connection: {
|
|
192
|
-
// host: 'localhost',
|
|
193
|
-
// port: 5432,
|
|
194
|
-
// user: 'myuser',
|
|
195
|
-
// password: 'mypassword',
|
|
196
|
-
// database: 'i18n_dashboard',
|
|
197
|
-
// },
|
|
198
|
-
},
|
|
199
|
-
|
|
200
|
-
// Google Translate API key (optional — free tier works without a key)
|
|
201
|
-
// googleTranslate: {
|
|
202
|
-
// apiKey: process.env.GOOGLE_TRANSLATE_API_KEY,
|
|
203
|
-
// },
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Environment variables
|
|
208
|
-
|
|
209
|
-
All options can be passed as environment variables (useful for CI/CD and Docker):
|
|
210
|
-
|
|
211
|
-
| Variable | Description | Default |
|
|
212
|
-
|---|---|---|
|
|
213
|
-
| `I18N_PORT` | Server port | `3333` |
|
|
214
|
-
| `I18N_DB_CLIENT` | DB driver (`better-sqlite3` / `pg` / `mysql2`) | `better-sqlite3` |
|
|
215
|
-
| `I18N_DB_CONNECTION` | SQLite file path | `./i18n-dashboard.db` |
|
|
216
|
-
| `I18N_DB_HOST` | PostgreSQL/MySQL host | `localhost` |
|
|
217
|
-
| `I18N_DB_PORT` | PostgreSQL/MySQL port | `5432` |
|
|
218
|
-
| `I18N_DB_USER` | Database user | — |
|
|
219
|
-
| `I18N_DB_PASSWORD` | Database password | — |
|
|
220
|
-
| `I18N_DB_NAME` | Database name | `i18n_dashboard` |
|
|
221
|
-
| `I18N_KEY_SEPARATOR` | Key separator | `.` |
|
|
222
|
-
| `I18N_API_PATH` | Locale API path pattern | `/locale/[lang].json` |
|
|
223
|
-
| `I18N_PROJECT_ROOT` | Project root path | `process.cwd()` |
|
|
224
|
-
| `I18N_LOCALES_PATH` | Locales folder (relative to root) | `src/locales` |
|
|
225
|
-
| `GOOGLE_TRANSLATE_API_KEY` | Google Translate API key | — |
|
|
226
|
-
| `SESSION_SECRET` | Session encryption secret | *(default, change in prod)* |
|
|
227
|
-
| `SMTP_HOST` | SMTP server for email | — |
|
|
228
|
-
| `DASHBOARD_URL` | Public URL of the dashboard | `http://localhost:3333` |
|
|
56
|
+
👉 Best for simple setups
|
|
229
57
|
|
|
230
58
|
---
|
|
231
59
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
```
|
|
235
|
-
i18n-dashboard <command> [options]
|
|
236
|
-
|
|
237
|
-
Commands:
|
|
238
|
-
start Start the dashboard server
|
|
239
|
-
stop Stop a running detached dashboard
|
|
240
|
-
build Build for production
|
|
241
|
-
init Run the interactive setup wizard
|
|
242
|
-
sync Import locale JSON files into the database
|
|
243
|
-
|
|
244
|
-
Options for start:
|
|
245
|
-
-p, --port <port> Server port (default: 3333)
|
|
246
|
-
--detach Run in the background (writes PID file)
|
|
247
|
-
|
|
248
|
-
Global options:
|
|
249
|
-
-V, --version Show version
|
|
250
|
-
-h, --help Show help
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Background mode
|
|
60
|
+
### 🔵 Server Mode
|
|
254
61
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
62
|
+
- Central dashboard for multiple projects
|
|
63
|
+
- API-based (no JSON handling)
|
|
64
|
+
- Git sync
|
|
258
65
|
|
|
259
|
-
|
|
260
|
-
npx i18n-dashboard stop
|
|
261
|
-
```
|
|
66
|
+
👉 Best for teams & scaling
|
|
262
67
|
|
|
263
68
|
---
|
|
264
69
|
|
|
265
|
-
##
|
|
266
|
-
|
|
267
|
-
### Dashboard
|
|
268
|
-
|
|
269
|
-
Customizable widget grid. Available widgets:
|
|
270
|
-
- **Total keys** — overall key count
|
|
271
|
-
- **Coverage** — global translation coverage percentage
|
|
272
|
-
- **Languages** — number of configured languages
|
|
273
|
-
- **Unused keys** — keys not found in source code
|
|
274
|
-
- **Language coverage** — per-language progress bars
|
|
275
|
-
- **Recent activity** — latest translation edits
|
|
276
|
-
- **Review queue** — translations awaiting approval
|
|
277
|
-
- **Projects** — quick project overview
|
|
278
|
-
|
|
279
|
-
Click **Edit** to add, remove, or rearrange widgets.
|
|
280
|
-
|
|
281
|
-
### Translations
|
|
282
|
-
|
|
283
|
-
The main translation table with:
|
|
284
|
-
- Search by key name (real-time)
|
|
285
|
-
- Filter by language and status (`All`, `Draft`, `Reviewed`, `Approved`, `Missing`, `Unused`)
|
|
286
|
-
- Status badge per language
|
|
287
|
-
- Auto-translate per key (Google Translate)
|
|
288
|
-
- Batch auto-translate for an entire language
|
|
289
|
-
|
|
290
|
-
Click any key to open its **detail page**:
|
|
291
|
-
- Edit each language with the full toolbar (params, escape helpers, plural editor, linked key picker)
|
|
292
|
-
- View translation history with one-click restore
|
|
293
|
-
- See which source files reference this key (after scan)
|
|
294
|
-
|
|
295
|
-
#### Plural editor
|
|
296
|
-
|
|
297
|
-
Switch any translation to plural mode to get a template-based form:
|
|
298
|
-
|
|
299
|
-
| Template | Languages | Example |
|
|
300
|
-
|---|---|---|
|
|
301
|
-
| 2 forms — standard | English, German, Dutch… | `car \| cars` |
|
|
302
|
-
| 3 forms — zero/one/many | French, Spanish, Italian… | `no cars \| {count} car \| {count} cars` |
|
|
303
|
-
| 4 forms — Slavic | Russian, Polish, Ukrainian… | `0 машин \| {n} машина \| {n} машины \| {n} машин` |
|
|
304
|
-
| Custom | Any | Define your own forms |
|
|
70
|
+
## 🎯 Why this tool?
|
|
305
71
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
-
|
|
311
|
-
- Type any custom BCP 47 code if it's not in the list
|
|
312
|
-
- Set a default language (source for auto-translate)
|
|
313
|
-
- Configure fallback chains:
|
|
314
|
-
- **Automatic** — `fr-CA → fr` (BCP 47 parent)
|
|
315
|
-
- **Manual** — pick any other configured language
|
|
316
|
-
- **None** — no fallback
|
|
317
|
-
- The API resolves the fallback chain transparently and merges translations
|
|
318
|
-
|
|
319
|
-
### Scan
|
|
320
|
-
|
|
321
|
-
Click **Scan project** in the sidebar or on any project card to open the scan modal.
|
|
322
|
-
|
|
323
|
-
**Local mode** — browse your file system with the folder picker and scan `.vue`, `.ts`, `.js` files for:
|
|
324
|
-
- `$t('key')`, `$tc()`, `$te()`, `$tm()`
|
|
325
|
-
- `t('key')` via `useI18n()`
|
|
326
|
-
- `<i18n-t keypath="key">`
|
|
327
|
-
- `v-t="'key'"`
|
|
328
|
-
- `<i18n>` SFC blocks
|
|
329
|
-
|
|
330
|
-
**Git mode** — enter a git repository URL (and optionally a branch and access token); the scanner clones the repo (shallow, depth 1), scans all source files, and also imports locale JSON files to populate missing translations in one step. Useful for CI environments or when you don't have a local checkout.
|
|
331
|
-
|
|
332
|
-
> Required token permission: **Contents → Read** (GitHub fine-grained PAT) or **repo** scope (classic PAT).
|
|
333
|
-
|
|
334
|
-
Results displayed inline: keys found, new keys, unused keys, files scanned, languages added, translations imported.
|
|
335
|
-
|
|
336
|
-
### Settings
|
|
337
|
-
|
|
338
|
-
Per-project settings (editable inline):
|
|
339
|
-
- **Project name, root path, locales folder, key separator, color, description**
|
|
340
|
-
- **App URLs** — one URL per line; all are accepted for CORS on `/locale/[lang].json`, the first is used for URL-based scan/sync
|
|
341
|
-
- **Git repository** — URL, branch, and access token for Git scan mode (token stored in DB, never exposed in the UI after save)
|
|
342
|
-
- **Advanced features** — enable/disable Number formats, Datetime formats, Custom modifiers pages
|
|
343
|
-
- **Scanner** — configure excluded directories
|
|
344
|
-
- **Google Translate** — optional API key
|
|
345
|
-
- **Export** — download locale JSON files per language or all at once
|
|
346
|
-
- **Snapshot** — export/import a full project backup
|
|
347
|
-
|
|
348
|
-
### Number Formats *(requires enable in Settings)*
|
|
349
|
-
|
|
350
|
-
Configure `$n(value, 'formatName')` presets:
|
|
351
|
-
- Group by locale
|
|
352
|
-
- Style: `decimal`, `currency`, `percent`, `unit`
|
|
353
|
-
- Currency / unit selection
|
|
354
|
-
- Live `Intl.NumberFormat` preview
|
|
355
|
-
|
|
356
|
-
### Datetime Formats *(requires enable in Settings)*
|
|
357
|
-
|
|
358
|
-
Configure `$d(date, 'formatName')` presets:
|
|
359
|
-
- Shortcut styles: `dateStyle` / `timeStyle`
|
|
360
|
-
- Individual fields: `year`, `month`, `day`, `hour`, `minute`, `second`, `weekday`, `era`, `timeZone`
|
|
361
|
-
- Live `Intl.DateTimeFormat` preview
|
|
362
|
-
|
|
363
|
-
### Modifiers *(requires enable in Settings)*
|
|
364
|
-
|
|
365
|
-
Define custom `@.modifier:key` transform functions:
|
|
366
|
-
- Write JS function body
|
|
367
|
-
- Live test runner
|
|
368
|
-
- Quick templates: `snakeCase`, `camelCase`, `kebabCase`, `titleCase`
|
|
369
|
-
|
|
370
|
-
### Snippet generator
|
|
371
|
-
|
|
372
|
-
Available on all format pages — generates a ready-to-paste `createI18n()` configuration including all your number formats, datetime formats, and custom modifiers.
|
|
373
|
-
|
|
374
|
-
### Project Snapshot
|
|
375
|
-
|
|
376
|
-
Export a complete project backup:
|
|
377
|
-
|
|
378
|
-
```json
|
|
379
|
-
{
|
|
380
|
-
"version": 1,
|
|
381
|
-
"exportedAt": "2026-01-01T00:00:00.000Z",
|
|
382
|
-
"project": { "name": "My App", "locales_path": "src/locales", "key_separator": "." },
|
|
383
|
-
"languages": [{ "code": "en", "name": "English", "is_default": true }],
|
|
384
|
-
"keys": [
|
|
385
|
-
{
|
|
386
|
-
"key": "home.title",
|
|
387
|
-
"description": "Homepage title",
|
|
388
|
-
"translations": {
|
|
389
|
-
"en": { "value": "Welcome", "status": "approved" },
|
|
390
|
-
"fr": { "value": "Bienvenue", "status": "reviewed" }
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
]
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
Import modes:
|
|
398
|
-
- **Merge** — add/update keys without touching existing ones
|
|
399
|
-
- **Replace** — delete everything and reimport clean
|
|
72
|
+
- Works with vue-i18n (no migration)
|
|
73
|
+
- Self-hosted (no lock-in)
|
|
74
|
+
- Multi-project support
|
|
75
|
+
- Git-friendly workflow
|
|
76
|
+
- Developer-first experience
|
|
400
77
|
|
|
401
78
|
---
|
|
402
79
|
|
|
403
|
-
##
|
|
404
|
-
|
|
405
|
-
### Basic (load all on startup)
|
|
406
|
-
|
|
407
|
-
```js
|
|
408
|
-
// src/i18n.js
|
|
409
|
-
import { createI18n } from 'vue-i18n'
|
|
410
|
-
|
|
411
|
-
const DASHBOARD = 'http://localhost:3333'
|
|
412
|
-
|
|
413
|
-
export const i18n = createI18n({
|
|
414
|
-
locale: 'en',
|
|
415
|
-
fallbackLocale: 'en',
|
|
416
|
-
messages: {
|
|
417
|
-
en: await fetch(`${DASHBOARD}/locale/en.json`).then(r => r.json()),
|
|
418
|
-
fr: await fetch(`${DASHBOARD}/locale/fr.json`).then(r => r.json()),
|
|
419
|
-
},
|
|
420
|
-
})
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
### With lazy loading
|
|
424
|
-
|
|
425
|
-
```js
|
|
426
|
-
import { createI18n } from 'vue-i18n'
|
|
80
|
+
## 📘 Documentation
|
|
427
81
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
export const i18n = createI18n({ locale: 'en', fallbackLocale: 'en', messages: {} })
|
|
431
|
-
|
|
432
|
-
export async function setLocale(locale) {
|
|
433
|
-
if (!i18n.global.availableLocales.includes(locale)) {
|
|
434
|
-
const messages = await fetch(`${DASHBOARD}/locale/${locale}.json`).then(r => r.json())
|
|
435
|
-
i18n.global.setLocaleMessage(locale, messages)
|
|
436
|
-
}
|
|
437
|
-
i18n.global.locale.value = locale
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
### With BCP 47 fallbacks
|
|
442
|
-
|
|
443
|
-
The API automatically resolves fallback chains. If `fr-CA` isn't fully translated, missing keys fall back to `fr`, then to the next configured fallback:
|
|
444
|
-
|
|
445
|
-
```
|
|
446
|
-
GET /locale/fr-CA.json → merges fr + fr-CA (fr-CA takes precedence)
|
|
447
|
-
X-I18n-Fallback-Chain: fr-CA → fr
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
No configuration needed on the client side.
|
|
451
|
-
|
|
452
|
-
### For production
|
|
453
|
-
|
|
454
|
-
Export locale files into your project and include them in your build:
|
|
455
|
-
|
|
456
|
-
```bash
|
|
457
|
-
curl http://localhost:3333/locale/en.json -o src/locales/en.json
|
|
458
|
-
curl http://localhost:3333/locale/fr.json -o src/locales/fr.json
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
Or deploy the dashboard on an internal server and keep using the API.
|
|
82
|
+
- See USAGE.md for workflows
|
|
83
|
+
- See DOCUMENTATION.md for full technical details
|
|
462
84
|
|
|
463
85
|
---
|
|
464
86
|
|
|
465
|
-
##
|
|
466
|
-
|
|
467
|
-
### SQLite (default — zero config)
|
|
468
|
-
|
|
469
|
-
```js
|
|
470
|
-
database: {
|
|
471
|
-
client: 'better-sqlite3',
|
|
472
|
-
connection: './i18n-dashboard.db',
|
|
473
|
-
}
|
|
474
|
-
```
|
|
475
|
-
|
|
476
|
-
The `.db` file is created automatically. No setup needed.
|
|
477
|
-
|
|
478
|
-
### PostgreSQL
|
|
479
|
-
|
|
480
|
-
```bash
|
|
481
|
-
npm install pg
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
```js
|
|
485
|
-
database: {
|
|
486
|
-
client: 'pg',
|
|
487
|
-
connection: {
|
|
488
|
-
host: 'localhost',
|
|
489
|
-
port: 5432,
|
|
490
|
-
user: 'myuser',
|
|
491
|
-
password: 'mypassword',
|
|
492
|
-
database: 'i18n_dashboard',
|
|
493
|
-
},
|
|
494
|
-
}
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
### MySQL / MariaDB
|
|
498
|
-
|
|
499
|
-
```bash
|
|
500
|
-
npm install mysql2
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
```js
|
|
504
|
-
database: {
|
|
505
|
-
client: 'mysql2',
|
|
506
|
-
connection: {
|
|
507
|
-
host: 'localhost',
|
|
508
|
-
port: 3306,
|
|
509
|
-
user: 'myuser',
|
|
510
|
-
password: 'mypassword',
|
|
511
|
-
database: 'i18n_dashboard',
|
|
512
|
-
},
|
|
513
|
-
}
|
|
514
|
-
```
|
|
515
|
-
|
|
516
|
-
### Schema
|
|
517
|
-
|
|
518
|
-
Tables are created and migrated automatically on startup:
|
|
519
|
-
|
|
520
|
-
```
|
|
521
|
-
projects — multi-project support
|
|
522
|
-
languages — per-project language list (BCP 47 codes, fallback_code)
|
|
523
|
-
translation_keys — key registry (key, description, is_unused, usages)
|
|
524
|
-
translations — values per key per language (value, status)
|
|
525
|
-
translation_history — full edit history (old_value, new_value, changed_by)
|
|
526
|
-
key_usages — source file references (file_path, line_number, function)
|
|
527
|
-
settings — global settings (scan_exclude, google_translate_api_key)
|
|
528
|
-
users — dashboard users (name, email, role, bcrypt password)
|
|
529
|
-
project_number_formats — Intl.NumberFormat presets
|
|
530
|
-
project_datetime_formats — Intl.DateTimeFormat presets
|
|
531
|
-
project_modifiers — custom @.modifier functions
|
|
532
|
-
```
|
|
533
|
-
|
|
534
|
-
---
|
|
535
|
-
|
|
536
|
-
## REST API
|
|
537
|
-
|
|
538
|
-
All endpoints require a `project_id` parameter.
|
|
539
|
-
|
|
540
|
-
### Locale export (main endpoint for vue-i18n)
|
|
541
|
-
|
|
542
|
-
```http
|
|
543
|
-
GET /locale/:lang.json?project_id=1
|
|
544
|
-
```
|
|
545
|
-
|
|
546
|
-
Returns nested JSON with all translations for the given language. Resolves fallback chains automatically.
|
|
547
|
-
|
|
548
|
-
**Response headers:**
|
|
549
|
-
- `X-I18n-Fallback-Chain: fr-CA → fr` — debug the resolved chain
|
|
550
|
-
|
|
551
|
-
### Projects
|
|
552
|
-
|
|
553
|
-
```http
|
|
554
|
-
GET /api/projects
|
|
555
|
-
POST /api/projects
|
|
556
|
-
PUT /api/projects/:id
|
|
557
|
-
DELETE /api/projects/:id
|
|
558
|
-
```
|
|
559
|
-
|
|
560
|
-
### Languages
|
|
561
|
-
|
|
562
|
-
```http
|
|
563
|
-
GET /api/languages?project_id=1
|
|
564
|
-
POST /api/languages
|
|
565
|
-
PUT /api/languages/:id
|
|
566
|
-
DELETE /api/languages/:code?project_id=1
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
### Translation keys
|
|
570
|
-
|
|
571
|
-
```http
|
|
572
|
-
GET /api/keys?project_id=1&search=&lang=&status=&page=1&limit=50
|
|
573
|
-
GET /api/keys/:id
|
|
574
|
-
POST /api/keys
|
|
575
|
-
PATCH /api/keys/:id
|
|
576
|
-
DELETE /api/keys/:id
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
### Translations
|
|
580
|
-
|
|
581
|
-
```http
|
|
582
|
-
POST /api/translations # Save a translation value
|
|
583
|
-
POST /api/translations/status # Update status only
|
|
584
|
-
POST /api/translations/batch-translate # Auto-translate all missing for a language
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
### Scan & Sync
|
|
588
|
-
|
|
589
|
-
```http
|
|
590
|
-
POST /api/scan # body: { project_id, mode: 'local'|'git', root_path?, git_url?, git_branch?, git_token? }
|
|
591
|
-
POST /api/sync # body: { project_id } — uses project's configured git repo or local path
|
|
592
|
-
POST /api/projects/detect # body: { root_path?, git_url?, git_branch?, git_token? }
|
|
593
|
-
GET /api/projects/check-name?name=&exclude_id= # Availability check
|
|
594
|
-
```
|
|
595
|
-
|
|
596
|
-
### Project Snapshot
|
|
597
|
-
|
|
598
|
-
```http
|
|
599
|
-
GET /api/project-snapshot?project_id=1 # Export
|
|
600
|
-
POST /api/project-snapshot # Import
|
|
601
|
-
body: { snapshot, project_id?, mode: 'merge'|'replace' }
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
### Advanced formats
|
|
605
|
-
|
|
606
|
-
```http
|
|
607
|
-
GET /api/formats/number?project_id=1
|
|
608
|
-
POST /api/formats/number
|
|
609
|
-
PUT /api/formats/number/:id
|
|
610
|
-
DELETE /api/formats/number/:id
|
|
611
|
-
|
|
612
|
-
GET /api/formats/datetime?project_id=1
|
|
613
|
-
POST /api/formats/datetime
|
|
614
|
-
PUT /api/formats/datetime/:id
|
|
615
|
-
DELETE /api/formats/datetime/:id
|
|
616
|
-
|
|
617
|
-
GET /api/formats/modifiers?project_id=1
|
|
618
|
-
POST /api/formats/modifiers
|
|
619
|
-
PUT /api/formats/modifiers/:id
|
|
620
|
-
DELETE /api/formats/modifiers/:id
|
|
621
|
-
|
|
622
|
-
GET /api/formats/snippet?project_id=1 # Generate createI18n() config snippet
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
### Users
|
|
626
|
-
|
|
627
|
-
```http
|
|
628
|
-
GET /api/users # All users (super admin / global admin)
|
|
629
|
-
GET /api/users?project_id=1 # Members of a project
|
|
630
|
-
GET /api/users?exclude_project_id=1 # Users not yet in a project (for the add picker)
|
|
631
|
-
POST /api/users # Create user
|
|
632
|
-
PUT /api/users/:id # Update user (name, is_active, role)
|
|
633
|
-
PUT /api/users/:id/roles # Bulk-update role assignments across projects
|
|
634
|
-
DELETE /api/users/:id?project_id=1 # Remove user from project (or globally if super admin)
|
|
635
|
-
GET /api/users/:id/profile?period=30d # Full user profile with activity stats
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
### Settings
|
|
639
|
-
|
|
640
|
-
```http
|
|
641
|
-
GET /api/settings
|
|
642
|
-
POST /api/settings
|
|
643
|
-
```
|
|
644
|
-
|
|
645
|
-
### File system browser
|
|
646
|
-
|
|
647
|
-
```http
|
|
648
|
-
GET /api/fs/browse?path=/some/path # List subdirectories; defaults to home dir
|
|
649
|
-
```
|
|
650
|
-
|
|
651
|
-
---
|
|
652
|
-
|
|
653
|
-
## User Roles
|
|
654
|
-
|
|
655
|
-
| Role | Permissions |
|
|
656
|
-
|---|---|
|
|
657
|
-
| **Super Admin** | Full access to all projects, users, and global settings |
|
|
658
|
-
| **Admin** | Full access to assigned projects |
|
|
659
|
-
| **Moderator** | Edit translations, approve/reject in review queue |
|
|
660
|
-
| **Translator** | Edit translations, mark as reviewed (cannot approve) |
|
|
661
|
-
|
|
662
|
-
---
|
|
663
|
-
|
|
664
|
-
## Recommended Workflows
|
|
665
|
-
|
|
666
|
-
### New project from scratch
|
|
667
|
-
|
|
668
|
-
```bash
|
|
669
|
-
# 1. Install
|
|
670
|
-
npm install i18n-dashboard --save-dev
|
|
671
|
-
|
|
672
|
-
# 2. Initialize
|
|
673
|
-
npx i18n-dashboard init
|
|
674
|
-
|
|
675
|
-
# 3. Start
|
|
676
|
-
npx i18n-dashboard start
|
|
677
|
-
|
|
678
|
-
# 4. In the UI:
|
|
679
|
-
# - Add languages (Languages tab)
|
|
680
|
-
# - Add translation keys (Translations tab)
|
|
681
|
-
# - Use the API in your Vue app
|
|
682
|
-
```
|
|
683
|
-
|
|
684
|
-
### Migrate from existing JSON files
|
|
685
|
-
|
|
686
|
-
```bash
|
|
687
|
-
# 1. Install and initialize
|
|
688
|
-
npm install i18n-dashboard --save-dev
|
|
689
|
-
npx i18n-dashboard init
|
|
690
|
-
|
|
691
|
-
# 2. Start
|
|
692
|
-
npx i18n-dashboard start
|
|
693
|
-
|
|
694
|
-
# 3. Sync your existing locale files
|
|
695
|
-
npx i18n-dashboard sync
|
|
696
|
-
|
|
697
|
-
# 4. All keys and translations are now in the database
|
|
698
|
-
```
|
|
699
|
-
|
|
700
|
-
### Team workflow with review
|
|
701
|
-
|
|
702
|
-
1. **Translators** edit keys → status: `Draft`
|
|
703
|
-
2. **Translators** mark ready → status: `Reviewed`
|
|
704
|
-
3. **Moderators/Admins** approve → status: `Approved`
|
|
705
|
-
4. Only `Approved` translations are exported (or all, depending on your needs)
|
|
706
|
-
|
|
707
|
-
### Move between environments (local → production)
|
|
708
|
-
|
|
709
|
-
```bash
|
|
710
|
-
# On local machine: export snapshot
|
|
711
|
-
# Dashboard UI → Settings → Snapshot → Export
|
|
712
|
-
|
|
713
|
-
# On production server: import snapshot
|
|
714
|
-
# Dashboard UI → Settings → Snapshot → Import (Merge or Replace mode)
|
|
715
|
-
```
|
|
716
|
-
|
|
717
|
-
---
|
|
718
|
-
|
|
719
|
-
## Stack
|
|
720
|
-
|
|
721
|
-
| Technology | Version | Role |
|
|
722
|
-
|---|---|---|
|
|
723
|
-
| [Nuxt 3](https://nuxt.com/) | 3.21+ | Full-stack framework (Nitro backend + Vue 3 frontend) |
|
|
724
|
-
| [Nuxt UI](https://ui.nuxt.com/) | 3.3+ | UI components (Tailwind CSS v4 + Reka UI) |
|
|
725
|
-
| [Knex.js](https://knexjs.org/) | 3.x | Multi-database abstraction |
|
|
726
|
-
| [better-sqlite3](https://github.com/WiseLibs/better-sqlite3) | 11.x | SQLite driver |
|
|
727
|
-
| [@vitalets/google-translate-api](https://github.com/vitalets/google-translate-api) | 9.x | Google Translate (free tier) |
|
|
728
|
-
| [Commander.js](https://github.com/tj/commander.js) | 13.x | CLI |
|
|
729
|
-
| [bcryptjs](https://github.com/dcodeIO/bcrypt.js) | 2.x | Password hashing |
|
|
730
|
-
| [Cypress](https://www.cypress.io/) | 13.x | E2E test suite |
|
|
731
|
-
| [Vitest](https://vitest.dev/) | 4.x | Unit test suite (composables, services, server utils) |
|
|
732
|
-
---
|
|
733
|
-
|
|
734
|
-
## Contributing
|
|
735
|
-
|
|
736
|
-
Contributions are welcome. Please open an issue before submitting a pull request for significant changes.
|
|
737
|
-
|
|
738
|
-
```bash
|
|
739
|
-
git clone https://github.com/arnaudprioul/i18n-dashboard.git
|
|
740
|
-
cd i18n-dashboard
|
|
741
|
-
npm install
|
|
742
|
-
|
|
743
|
-
# Register the project git hooks (one-time, per clone)
|
|
744
|
-
git config core.hooksPath .githooks
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
### Commit message convention
|
|
748
|
-
|
|
749
|
-
Every push to `main` must include at least one commit message with a version bump indicator:
|
|
750
|
-
|
|
751
|
-
| Indicator | Bump | Example |
|
|
752
|
-
|---|---|---|
|
|
753
|
-
| `[patch]` | `0.3.8 → 0.3.9` | `fix: correct typo in error message [patch]` |
|
|
754
|
-
| `[minor]` | `0.3.8 → 0.4.0` | `feat: add git scan mode [minor]` |
|
|
755
|
-
| `[major]` | `0.3.8 → 1.0.0` | `feat!: breaking API change [major]` |
|
|
756
|
-
|
|
757
|
-
The pre-push hook will block the push if:
|
|
758
|
-
- No `[major]`, `[minor]`, or `[patch]` indicator is found in the commits
|
|
759
|
-
- `README.md` has not been updated
|
|
760
|
-
|
|
761
|
-
If both checks pass, the CI automatically bumps `package.json`, creates the git tag, and triggers the npm publish workflow.
|
|
762
|
-
|
|
763
|
-
---
|
|
764
|
-
|
|
765
|
-
## Support
|
|
766
|
-
|
|
767
|
-
If this project saved you time, consider buying me a coffee ☕
|
|
87
|
+
## 💬 Feedback
|
|
768
88
|
|
|
769
|
-
|
|
89
|
+
Looking for feedback 👀
|
|
90
|
+
Open an issue or discussion!
|
|
770
91
|
|
|
771
92
|
---
|
|
772
93
|
|
|
773
|
-
## License
|
|
94
|
+
## 📄 License
|
|
774
95
|
|
|
775
|
-
|
|
96
|
+
MIT
|
|
776
97
|
|
|
777
98
|
---
|
|
778
99
|
|
|
779
|
-
Made with ❤️ by [arnaudprioul](https://github.com/arnaudprioul)
|