@proulr/rosetta 0.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 +49 -0
- package/docs/ROSETTA.md +247 -0
- package/docs/npm-publish-cicd.md +50 -0
- package/package.json +49 -0
- package/src/catalog.ts +42 -0
- package/src/domains.ts +18 -0
- package/src/generated/locale-messages.ts +925 -0
- package/src/index.ts +20 -0
- package/src/locale-types.ts +13 -0
- package/src/locales/en/alerts.json +40 -0
- package/src/locales/en/auth.json +46 -0
- package/src/locales/en/chat.json +22 -0
- package/src/locales/en/common.json +28 -0
- package/src/locales/en/discover.json +33 -0
- package/src/locales/en/flash.json +16 -0
- package/src/locales/en/hybrid.json +10 -0
- package/src/locales/en/profile.json +65 -0
- package/src/locales/en/shell.json +201 -0
- package/src/locales/en/social.json +12 -0
- package/src/locales/pt-BR/alerts.json +40 -0
- package/src/locales/pt-BR/auth.json +46 -0
- package/src/locales/pt-BR/chat.json +22 -0
- package/src/locales/pt-BR/common.json +28 -0
- package/src/locales/pt-BR/discover.json +33 -0
- package/src/locales/pt-BR/flash.json +16 -0
- package/src/locales/pt-BR/hybrid.json +10 -0
- package/src/locales/pt-BR/profile.json +65 -0
- package/src/locales/pt-BR/shell.json +201 -0
- package/src/locales/pt-BR/social.json +12 -0
- package/src/resolve-locale.ts +85 -0
- package/src/translate.ts +18 -0
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# @proulr/rosetta
|
|
2
|
+
|
|
3
|
+
Fonte única de i18n do Proulr (padrão Rosetta): copy de produto para BFFs e app nativo.
|
|
4
|
+
|
|
5
|
+
- **GitHub:** https://github.com/saviorbp/proulr-rosetta
|
|
6
|
+
- **npm:** https://www.npmjs.com/package/@proulr/rosetta
|
|
7
|
+
- **Guia:** [docs/ROSETTA.md](./docs/ROSETTA.md)
|
|
8
|
+
- **CI/CD:** [docs/npm-publish-cicd.md](./docs/npm-publish-cicd.md)
|
|
9
|
+
|
|
10
|
+
## Formato
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
src/locales/<locale>/<domain>.json # editar (flat JSON)
|
|
14
|
+
src/generated/locale-messages.ts # gerado — Metro importa só .ts
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`pt-BR` = source of truth das keys. Após editar JSON: `npm run locale:generate`.
|
|
18
|
+
|
|
19
|
+
## Uso rápido
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { t, tFormat, resolveLocaleFromQuery } from '@proulr/rosetta';
|
|
23
|
+
|
|
24
|
+
const locale = resolveLocaleFromQuery(ctx.query);
|
|
25
|
+
t('discover.filter.all', locale);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Scripts
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm run locale:add -- es # novo idioma (JSON vazio + wiring)
|
|
32
|
+
npm run locale:generate # regenera types/catalog
|
|
33
|
+
npm run validate:locales # parity de keys + imports (pre-commit)
|
|
34
|
+
npm run check:locales:strict # sem valores vazios
|
|
35
|
+
npm run typecheck
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Pre-commit
|
|
39
|
+
|
|
40
|
+
Ao commit, o hook roda `validate:locales`:
|
|
41
|
+
|
|
42
|
+
- Key nova → deve existir em **todos** os idiomas
|
|
43
|
+
- Key removida → deve sumir de **todos** os idiomas
|
|
44
|
+
- Locale novo → todos os domains + `PROULR_LOCALES` + imports em `catalog.ts`
|
|
45
|
+
|
|
46
|
+
## Regras
|
|
47
|
+
|
|
48
|
+
- BFFs/app só consomem `t()` — zero dicionário local
|
|
49
|
+
- Default / fallback: `pt-BR`
|
package/docs/ROSETTA.md
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
# @proulr/rosetta — guia completo
|
|
2
|
+
|
|
3
|
+
Pacote de i18n do Proulr (inspirado na Rosetta da Nubank): **única fonte de copy** para BFFs (wire SDUI) e app nativo (auth, alerts, hybrids).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## O que foi feito
|
|
8
|
+
|
|
9
|
+
| Entrega | Detalhe |
|
|
10
|
+
|---------|---------|
|
|
11
|
+
| Pacote `@proulr/rosetta` | `t` / `tFormat` / resolve de locale |
|
|
12
|
+
| Formato JSON por locale | `src/locales/<locale>/<domain>.json` (escala para ~13 idiomas) |
|
|
13
|
+
| `pt-BR` | Fonte das keys; fallback se tradução vazia/ausente |
|
|
14
|
+
| Idiomas iniciais | `pt-BR`, `en` |
|
|
15
|
+
| App | `locale` em todo fetch SDUI; preferência AsyncStorage; auth com globe + tagline ciclando |
|
|
16
|
+
| BFFs | `resolveLocaleFromQuery` + `t()` nos builders BDC |
|
|
17
|
+
| Scripts | `locale:add`, `locale:generate`, `check:locales`, `validate:locales` |
|
|
18
|
+
| Pre-commit | Valida parity de keys + wiring (imports / `PROULR_LOCALES`) |
|
|
19
|
+
|
|
20
|
+
Consumidores (app + BFFs) **não** guardam dicionário de produto — só chamam `t(key, locale)`.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Arquitetura
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
preferência (system | pt-BR | en | …)
|
|
28
|
+
↓
|
|
29
|
+
app resolve locale (device / navigator)
|
|
30
|
+
↓
|
|
31
|
+
fetch SDUI ?locale=…
|
|
32
|
+
↓
|
|
33
|
+
BFF: t(key, locale) → wire já traduzido
|
|
34
|
+
↓
|
|
35
|
+
SduiScreenRenderer (não traduz)
|
|
36
|
+
|
|
37
|
+
App nativo (auth/Alert/hybrid): mesmo t() do Rosetta
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
| Quem | Papel |
|
|
41
|
+
|------|--------|
|
|
42
|
+
| **Rosetta** | Keys + traduções + `t` / `tFormat` |
|
|
43
|
+
| **BFFs** | Traduz na autoria BDC → wire |
|
|
44
|
+
| **App** | Resolve locale; nativo usa `t`; SDUI só renderiza |
|
|
45
|
+
| **SO** | Diálogos de permissão (fora do Rosetta) |
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Formato dos arquivos
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
src/locales/
|
|
53
|
+
pt-BR/ # source of truth (editar aqui)
|
|
54
|
+
common.json
|
|
55
|
+
…
|
|
56
|
+
en/
|
|
57
|
+
…
|
|
58
|
+
|
|
59
|
+
src/generated/
|
|
60
|
+
locale-messages.ts # AUTO-GERADO (Metro-safe) — não editar
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Edite só os JSON. Depois rode `npm run locale:generate` (o pre-commit também roda).
|
|
64
|
+
|
|
65
|
+
Cada JSON é **flat** (key → string):
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"auth.login.title": "Bem-vindo de volta",
|
|
70
|
+
"auth.login.submit": "Entrar"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Não** misturar idiomas no mesmo objeto. Um locale = uma pasta.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Uso no código
|
|
79
|
+
|
|
80
|
+
### BFF
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { t, tFormat, resolveLocaleFromQuery } from '@proulr/rosetta';
|
|
84
|
+
|
|
85
|
+
const locale = resolveLocaleFromQuery(ctx.query);
|
|
86
|
+
title={t('shell.settings.title', locale)}
|
|
87
|
+
subtitle={tFormat('discover.subtitle.huntingIn', locale, { label: city })}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### App nativo
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
import { t } from '@proulr/rosetta';
|
|
94
|
+
import { getResolvedAppLocale } from '@/lib/app-locale-service';
|
|
95
|
+
// ou
|
|
96
|
+
import { useAppLocale } from '@/hooks/use-app-locale';
|
|
97
|
+
|
|
98
|
+
const { t, locale, setPref } = useAppLocale();
|
|
99
|
+
t('auth.welcome.signIn');
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Query SDUI
|
|
103
|
+
|
|
104
|
+
O app envia `locale` (resolvido) em todo `buildSduiScreenFetchQuery`. Em settings também envia `app_locale` (preferência: `system` | idioma explícito).
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Scripts
|
|
109
|
+
|
|
110
|
+
Rodar **dentro** de `proulr-rosetta/`:
|
|
111
|
+
|
|
112
|
+
| Comando | O que faz |
|
|
113
|
+
|---------|-----------|
|
|
114
|
+
| `npm run locale:add -- es` | Cria pasta do idioma com keys vazias + regenera types/catalog |
|
|
115
|
+
| `npm run locale:add -- es-ES --force` | Idem, sobrescreve templates |
|
|
116
|
+
| `npm run locale:generate` | Regenera `locale-types.ts` + `catalog.ts` a partir de `src/locales` |
|
|
117
|
+
| `npm run check:locales` | Keys de `pt-BR` presentes em todos; vazios = warning |
|
|
118
|
+
| `npm run check:locales:strict` | Idem, mas valor vazio = erro |
|
|
119
|
+
| `npm run validate:locales` | Coverage + wiring (imports, `PROULR_LOCALES`, domains) |
|
|
120
|
+
| `npm run validate:locales:strict` | Validate + sem valores vazios |
|
|
121
|
+
| `npm run typecheck` | `validate:locales` + `tsc` |
|
|
122
|
+
| `npm run lint` | ESLint |
|
|
123
|
+
|
|
124
|
+
### Exemplos
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
# Novo idioma
|
|
128
|
+
npm run locale:add -- es
|
|
129
|
+
# editar src/locales/es/*.json
|
|
130
|
+
npm run check:locales:strict
|
|
131
|
+
|
|
132
|
+
# Nova key de copy
|
|
133
|
+
# 1. adicionar em src/locales/pt-BR/<domain>.json
|
|
134
|
+
# 2. adicionar a MESMA key em en/ (e demais locales)
|
|
135
|
+
# 3. npm run validate:locales
|
|
136
|
+
|
|
137
|
+
# Remover key
|
|
138
|
+
# apagar a key de TODOS os locales/<id>/<domain>.json
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Pre-commit
|
|
144
|
+
|
|
145
|
+
Hook em `.husky/pre-commit` (requer git no pacote — `git init` se ainda não houver remote):
|
|
146
|
+
|
|
147
|
+
1. **`npm run locale:generate`** — sincroniza `src/generated/locale-messages.ts` a partir dos JSON
|
|
148
|
+
2. **`npm run validate:locales`** — falha o commit se:
|
|
149
|
+
- Key nova em `pt-BR` sem a mesma key nos outros idiomas
|
|
150
|
+
- Key removida de `pt-BR` mas ainda presente em outro idioma
|
|
151
|
+
- Key “sobrando” em um locale sem existir em `pt-BR`
|
|
152
|
+
- Pasta de locale sem todos os `*.json` de domínio
|
|
153
|
+
- Locale no disco **sem** estar em `PROULR_LOCALES` / no `locale-messages.ts` gerado
|
|
154
|
+
3. **`lint-staged`** — ESLint nos arquivos staged
|
|
155
|
+
4. **`proulr-bump-and-sync-deps`** (se existir no monorepo) — bump de versão publishable
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
cd proulr-rosetta
|
|
159
|
+
npm install # prepare → husky
|
|
160
|
+
npm run validate:locales
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Workflows
|
|
166
|
+
|
|
167
|
+
### Nova string de produto
|
|
168
|
+
|
|
169
|
+
1. Escolher domínio (`auth`, `shell`, `discover`, …)
|
|
170
|
+
2. Adicionar key em **`pt-BR/<domain>.json`**
|
|
171
|
+
3. Adicionar a **mesma key** em **todos** os outros locales (mesmo que temporariamente com `""` ou já traduzido)
|
|
172
|
+
4. Usar `t('domain.key', locale)` no BFF ou app
|
|
173
|
+
5. Commit → pre-commit valida parity
|
|
174
|
+
|
|
175
|
+
### Novo idioma
|
|
176
|
+
|
|
177
|
+
1. `npm run locale:add -- <id>` (ex.: `es`, `zh-CN`)
|
|
178
|
+
2. Traduzir os JSONs gerados
|
|
179
|
+
3. `npm run check:locales:strict`
|
|
180
|
+
4. Atualizar UI do app (picker Settings / globe na ante-tela) para incluir o novo locale no ciclo de preferência
|
|
181
|
+
5. Commit
|
|
182
|
+
|
|
183
|
+
## Detecção de idioma (app)
|
|
184
|
+
|
|
185
|
+
| Preferência | Comportamento |
|
|
186
|
+
|-------------|---------------|
|
|
187
|
+
| `system` (default) | Mobile: `expo-localization`; Web: `navigator.languages` |
|
|
188
|
+
| `pt-BR` / `en` / … | Força o locale |
|
|
189
|
+
|
|
190
|
+
Troca na ante-tela (globe) ou em Settings → limpa cache SDUI → próximo fetch no novo idioma.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## CI/CD (GitHub Actions + npm)
|
|
195
|
+
|
|
196
|
+
Detalhes: [`docs/npm-publish-cicd.md`](./npm-publish-cicd.md).
|
|
197
|
+
|
|
198
|
+
Workflow: [`.github/workflows/publish-npm.yml`](../.github/workflows/publish-npm.yml)
|
|
199
|
+
|
|
200
|
+
| Evento | O que roda |
|
|
201
|
+
|--------|------------|
|
|
202
|
+
| PR / push em `main` (src, scripts, package*) | `npm run typecheck` |
|
|
203
|
+
| Push em `main` após CI ok | `npm publish --access public` via **Trusted Publishing (OIDC)** |
|
|
204
|
+
|
|
205
|
+
### Setup Trusted Publishing (primeira vez)
|
|
206
|
+
|
|
207
|
+
1. Em https://www.npmjs.com → scope `@proulr` → criar/`@proulr/rosetta` se precisar
|
|
208
|
+
2. **Trusted Publisher** → GitHub Actions
|
|
209
|
+
3. Repository: `saviorbp/proulr-rosetta`
|
|
210
|
+
4. Workflow filename: `publish-npm.yml`
|
|
211
|
+
5. Environment: vazio
|
|
212
|
+
|
|
213
|
+
Sem Trusted Publisher, o job `publish` falha (404/401). Depois do publish, consumers usam `"@proulr/rosetta": "^0.1.1"`.
|
|
214
|
+
|
|
215
|
+
---
|
|
216
|
+
|
|
217
|
+
## Regras
|
|
218
|
+
|
|
219
|
+
- Identificadores EN; copy via Rosetta; default `pt-BR`
|
|
220
|
+
- **Proibido** literal de produto em BFF/app
|
|
221
|
+
- Nova copy = PR no Rosetta (keys em todos os locales)
|
|
222
|
+
- Renderer SDUI **não** traduz
|
|
223
|
+
- Pre-commit deve passar antes do commit
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## Estrutura do pacote
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
proulr-rosetta/
|
|
231
|
+
src/
|
|
232
|
+
locales/ # JSON por locale/domínio
|
|
233
|
+
catalog.ts # merge + getMessage (gerado em parte via locale:generate)
|
|
234
|
+
locale-types.ts # ProulrLocale (gerado via locale:generate)
|
|
235
|
+
translate.ts # t / tFormat
|
|
236
|
+
resolve-locale.ts # query / pref / system tags
|
|
237
|
+
domains.ts
|
|
238
|
+
index.ts
|
|
239
|
+
scripts/
|
|
240
|
+
add-locale.mjs
|
|
241
|
+
generate-locale-wiring.mjs
|
|
242
|
+
check-locale-coverage.mjs
|
|
243
|
+
validate-locales.mjs
|
|
244
|
+
.husky/pre-commit
|
|
245
|
+
docs/ROSETTA.md # este guia
|
|
246
|
+
README.md # resumo + link
|
|
247
|
+
```
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Publicação automática no npm (CI/CD)
|
|
2
|
+
|
|
3
|
+
`@proulr/rosetta` publica no npm quando há push em `main` — mesmo fluxo de `@proulr/sdui-contract` e `@proulr/bff-core`.
|
|
4
|
+
|
|
5
|
+
## Fluxo
|
|
6
|
+
|
|
7
|
+
1. Altere o código da lib.
|
|
8
|
+
2. **Suba a versão** em `package.json` (ex.: `0.1.1` → `0.1.2`).
|
|
9
|
+
3. Rode `npm install` se mudou dependências (atualiza `package-lock.json`).
|
|
10
|
+
4. Commit, merge e push em `main`.
|
|
11
|
+
5. O workflow `.github/workflows/publish-npm.yml` roda typecheck e publica se a versão ainda não existir no npm.
|
|
12
|
+
|
|
13
|
+
Se a versão já estiver publicada, o job **pula** o publish (CI verde, sem erro).
|
|
14
|
+
|
|
15
|
+
## Autenticação no npm
|
|
16
|
+
|
|
17
|
+
### Bootstrap (1ª publicação do pacote)
|
|
18
|
+
|
|
19
|
+
OIDC/Trusted Publishing **só funciona depois que o pacote existe** no npm. Igual ao bootstrap de contract/core:
|
|
20
|
+
|
|
21
|
+
1. Crie um token **Automation** em https://www.npmjs.com/settings/~/tokens (ou reutilize o dos outros `@proulr/*`)
|
|
22
|
+
2. No GitHub:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
gh secret set NPM_TOKEN -R saviorbp/proulr-rosetta
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
3. Push / re-run do workflow → cria `@proulr/rosetta` no registry
|
|
29
|
+
|
|
30
|
+
### Trusted Publishing (depois do bootstrap — modo steady-state)
|
|
31
|
+
|
|
32
|
+
1. https://www.npmjs.com/package/@proulr/rosetta → **Settings** → **Trusted Publisher** → **GitHub Actions**
|
|
33
|
+
2. Preencha:
|
|
34
|
+
|
|
35
|
+
| Campo | Valor |
|
|
36
|
+
| --- | --- |
|
|
37
|
+
| Organization or user | `saviorbp` |
|
|
38
|
+
| Repository | `proulr-rosetta` |
|
|
39
|
+
| Workflow filename | `publish-npm.yml` |
|
|
40
|
+
| Environment | *(vazio)* |
|
|
41
|
+
|
|
42
|
+
O workflow já tem `id-token: write`. Com Trusted Publisher configurado, o publish usa OIDC (o `NPM_TOKEN` fica só como fallback).
|
|
43
|
+
|
|
44
|
+
**Repositório privado no GitHub:** sem `--provenance`.
|
|
45
|
+
|
|
46
|
+
## Consumidores (app / BFFs)
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install @proulr/rosetta@^0.1.2
|
|
50
|
+
```
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@proulr/rosetta",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./src/index.ts",
|
|
6
|
+
"types": "./src/index.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./src/index.ts"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"README.md",
|
|
13
|
+
"docs"
|
|
14
|
+
],
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/saviorbp/proulr-rosetta.git"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"prepare": "husky",
|
|
21
|
+
"locale:add": "node ./scripts/add-locale.mjs",
|
|
22
|
+
"locale:generate": "node ./scripts/generate-locale-wiring.mjs",
|
|
23
|
+
"check:locales": "node ./scripts/check-locale-coverage.mjs",
|
|
24
|
+
"check:locales:strict": "node ./scripts/check-locale-coverage.mjs --strict",
|
|
25
|
+
"validate:locales": "node ./scripts/validate-locales.mjs",
|
|
26
|
+
"validate:locales:strict": "node ./scripts/validate-locales.mjs --strict",
|
|
27
|
+
"typecheck": "npm run locale:generate && npm run validate:locales && tsc --noEmit",
|
|
28
|
+
"prepublishOnly": "npm run typecheck",
|
|
29
|
+
"lint": "eslint .",
|
|
30
|
+
"lint:fix": "eslint . --fix",
|
|
31
|
+
"version:sync": "node ../scripts/proulr-bump-and-sync-deps.mjs"
|
|
32
|
+
},
|
|
33
|
+
"publishConfig": {
|
|
34
|
+
"access": "public"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@eslint/js": "^9.39.4",
|
|
38
|
+
"@types/node": "^22.20.0",
|
|
39
|
+
"eslint": "^9.0.0",
|
|
40
|
+
"globals": "^16.0.0",
|
|
41
|
+
"husky": "^9.1.7",
|
|
42
|
+
"lint-staged": "^16.4.0",
|
|
43
|
+
"typescript": "~6.0.3",
|
|
44
|
+
"typescript-eslint": "^8.61.1"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=22"
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/catalog.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { ProulrLocale } from './locale-types';
|
|
2
|
+
import { DEFAULT_PROULR_LOCALE } from './locale-types';
|
|
3
|
+
import { ROSETTA_DOMAINS } from './domains';
|
|
4
|
+
import {
|
|
5
|
+
MESSAGES_BY_LOCALE,
|
|
6
|
+
PT_BR_MESSAGES,
|
|
7
|
+
type FlatMessages,
|
|
8
|
+
type ProulrMessageKey,
|
|
9
|
+
EN_MESSAGES,
|
|
10
|
+
} from './generated/locale-messages';
|
|
11
|
+
|
|
12
|
+
export { PT_BR_MESSAGES, type ProulrMessageKey };
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Legacy nested shape (key → locale → string). Prefer `t(key, locale)`.
|
|
16
|
+
*/
|
|
17
|
+
export const PROULR_LOCALE_CATALOG = Object.fromEntries(
|
|
18
|
+
(Object.keys(PT_BR_MESSAGES) as ProulrMessageKey[]).map((key) => [
|
|
19
|
+
key,
|
|
20
|
+
{
|
|
21
|
+
'pt-BR': PT_BR_MESSAGES[key],
|
|
22
|
+
'en': EN_MESSAGES[key] ?? PT_BR_MESSAGES[key],
|
|
23
|
+
},
|
|
24
|
+
]),
|
|
25
|
+
) as {
|
|
26
|
+
[K in ProulrMessageKey]: Record<ProulrLocale, string>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export function getLocaleMessages(locale: ProulrLocale): FlatMessages {
|
|
30
|
+
return MESSAGES_BY_LOCALE[locale] ?? MESSAGES_BY_LOCALE[DEFAULT_PROULR_LOCALE];
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function getMessage(
|
|
34
|
+
key: ProulrMessageKey,
|
|
35
|
+
locale: ProulrLocale = DEFAULT_PROULR_LOCALE,
|
|
36
|
+
): string {
|
|
37
|
+
const primary = getLocaleMessages(locale)[key];
|
|
38
|
+
if (typeof primary === 'string' && primary.length > 0) return primary;
|
|
39
|
+
return PT_BR_MESSAGES[key] ?? key;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export { ROSETTA_DOMAINS };
|
package/src/domains.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain catalog files under `src/locales/<locale>/<domain>.json`.
|
|
3
|
+
* `pt-BR` is the source of truth for message keys.
|
|
4
|
+
*/
|
|
5
|
+
export const ROSETTA_DOMAINS = [
|
|
6
|
+
'common',
|
|
7
|
+
'shell',
|
|
8
|
+
'discover',
|
|
9
|
+
'chat',
|
|
10
|
+
'flash',
|
|
11
|
+
'profile',
|
|
12
|
+
'social',
|
|
13
|
+
'auth',
|
|
14
|
+
'alerts',
|
|
15
|
+
'hybrid',
|
|
16
|
+
] as const;
|
|
17
|
+
|
|
18
|
+
export type RosettaDomain = (typeof ROSETTA_DOMAINS)[number];
|