mapa-frontend-i18n 1.3.5 → 2.0.0
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 +264 -0
- package/fesm2022/mapa-frontend-i18n.mjs +178 -1
- package/fesm2022/mapa-frontend-i18n.mjs.map +1 -1
- package/index.d.ts +78 -2
- package/mapa-frontend-i18n-2.0.0.tgz +0 -0
- package/package.json +1 -1
- package/mapa-frontend-i18n-1.3.5.tgz +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# mapa-frontend-i18n
|
|
2
|
+
|
|
3
|
+
Biblioteca Angular de internacionalização (i18n) construída sobre
|
|
4
|
+
[`@angular/localize`](https://angular.dev/guide/i18n). Fornece os catálogos de
|
|
5
|
+
tradução do produto MAPA (pt-BR, en, es) e funções para inicializar o idioma da
|
|
6
|
+
aplicação.
|
|
7
|
+
|
|
8
|
+
A partir da **2.0**, as traduções podem ser carregadas de **arquivos JSON
|
|
9
|
+
hospedados na AWS (S3/CloudFront)**, permitindo corrigir termos e acentuação
|
|
10
|
+
**sem republicar a lib nem fazer redeploy das aplicações**. Os catálogos
|
|
11
|
+
embutidos continuam no pacote como _fallback_.
|
|
12
|
+
|
|
13
|
+
> **Compatibilidade:** a 2.0 é aditiva — a API síncrona da 1.x
|
|
14
|
+
> (`initializeAppLanguage`, `getMapaUiTexts`, tipos e catálogos) continua igual.
|
|
15
|
+
> O carregamento remoto é **opt-in** via `initializeAppLanguageAsync`. O major
|
|
16
|
+
> marca a mudança de arquitetura (traduções podem vir da rede), não uma quebra
|
|
17
|
+
> de API.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Sumário
|
|
22
|
+
|
|
23
|
+
- [Instalação](#instalação)
|
|
24
|
+
- [Como funciona](#como-funciona)
|
|
25
|
+
- [Inicialização](#inicialização)
|
|
26
|
+
- [Modo 1 — Embutido (síncrono)](#modo-1--embutido-síncrono)
|
|
27
|
+
- [Modo 2 — Remoto com fallback (recomendado)](#modo-2--remoto-com-fallback-recomendado)
|
|
28
|
+
- [Modo 3 — Host distribui aos MFEs](#modo-3--host-distribui-aos-mfes)
|
|
29
|
+
- [Opções de carregamento remoto](#opções-de-carregamento-remoto)
|
|
30
|
+
- [Cache e revalidação](#cache-e-revalidação)
|
|
31
|
+
- [Arquivos de tradução na AWS](#arquivos-de-tradução-na-aws)
|
|
32
|
+
- [Gerar/atualizar os JSON](#geraratualizar-os-json)
|
|
33
|
+
- [Processo de hotfix de termo](#processo-de-hotfix-de-termo-sem-republicar)
|
|
34
|
+
- [Requisitos de infraestrutura](#requisitos-de-infraestrutura-aws)
|
|
35
|
+
- [Outras APIs](#outras-apis)
|
|
36
|
+
- [Idiomas suportados](#idiomas-suportados)
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Instalação
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
npm install mapa-frontend-i18n
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`peerDependency`: `@angular/localize ~20.3.0` (já presente nas aplicações MAPA).
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Como funciona
|
|
51
|
+
|
|
52
|
+
- As traduções são um **mapa achatado** `{ "chave.do.localize": "texto" }`,
|
|
53
|
+
injetado no `@angular/localize` via `loadTranslations()`.
|
|
54
|
+
- O `$localize` resolve cada mensagem **no momento em que ela é avaliada**, usando
|
|
55
|
+
o mapa global. Por isso, **as traduções precisam ser carregadas antes do
|
|
56
|
+
`bootstrapApplication()`** — caso contrário a tela aparece com o texto-fonte
|
|
57
|
+
(pt-BR) ou com as chaves cruas.
|
|
58
|
+
- O carregamento remoto faz o merge `{ ...embutido, ...remoto }`: o remoto
|
|
59
|
+
**sobrescreve** o embutido, e qualquer chave ausente no remoto ainda resolve
|
|
60
|
+
pelo embutido. Ou seja, **arquivos remotos parciais são seguros**.
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Inicialização
|
|
65
|
+
|
|
66
|
+
### Modo 1 — Embutido (síncrono)
|
|
67
|
+
|
|
68
|
+
Usa apenas os catálogos embutidos no pacote. É o comportamento clássico, sem
|
|
69
|
+
rede.
|
|
70
|
+
|
|
71
|
+
```ts
|
|
72
|
+
import { initializeAppLanguage } from "mapa-frontend-i18n";
|
|
73
|
+
|
|
74
|
+
initializeAppLanguage(); // lê o idioma do localStorage e carrega o embutido
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Modo 2 — Remoto com fallback (recomendado)
|
|
78
|
+
|
|
79
|
+
Carrega da AWS, com cache local e _fallback_ automático para o embutido. **Deve
|
|
80
|
+
ser aguardado antes do bootstrap.**
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// main.ts
|
|
84
|
+
import { bootstrapApplication } from "@angular/platform-browser";
|
|
85
|
+
import { initializeAppLanguageAsync } from "mapa-frontend-i18n";
|
|
86
|
+
import { AppComponent } from "./app/app.component";
|
|
87
|
+
import { appConfig } from "./app/app.config";
|
|
88
|
+
import { environment } from "./environments/environment";
|
|
89
|
+
|
|
90
|
+
initializeAppLanguageAsync({ baseUrl: environment.i18nBaseUrl })
|
|
91
|
+
.catch(() => undefined) // nunca lança; em falha já usa o fallback embutido
|
|
92
|
+
.then(() => bootstrapApplication(AppComponent, appConfig));
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
`environment.i18nBaseUrl` aponta para a pasta que contém os JSON por idioma, por
|
|
96
|
+
ambiente (dev/staging/prod). Ex.: `https://cdn.mapa.com.br/i18n`.
|
|
97
|
+
|
|
98
|
+
### Modo 3 — Host distribui aos MFEs
|
|
99
|
+
|
|
100
|
+
Em micro-frontends, o **host** busca as traduções uma única vez e as repassa para
|
|
101
|
+
cada MFE, evitando um request por MFE. Use quando cada MFE roda em um contexto de
|
|
102
|
+
`@angular/localize` próprio.
|
|
103
|
+
|
|
104
|
+
```ts
|
|
105
|
+
// no host (antes do bootstrap):
|
|
106
|
+
import { getStoredAppLanguage, loadRemoteTranslations } from "mapa-frontend-i18n";
|
|
107
|
+
|
|
108
|
+
const language = getStoredAppLanguage();
|
|
109
|
+
const remote = await loadRemoteTranslations(language, {
|
|
110
|
+
baseUrl: environment.i18nBaseUrl,
|
|
111
|
+
});
|
|
112
|
+
// disponibilize `language` + `remote` para os MFEs (window, store compartilhado, etc.)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
```ts
|
|
116
|
+
// em cada MFE (antes do seu bootstrap):
|
|
117
|
+
import { initializeAppLanguageFromData } from "mapa-frontend-i18n";
|
|
118
|
+
|
|
119
|
+
initializeAppLanguageFromData(language, remote ?? {});
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
> Se os MFEs compartilham o mesmo `@angular/localize` (singleton via module
|
|
123
|
+
> federation), basta o host chamar `initializeAppLanguageAsync` uma vez.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
## Opções de carregamento remoto
|
|
128
|
+
|
|
129
|
+
`RemoteTranslationOptions` (usado por `initializeAppLanguageAsync` e
|
|
130
|
+
`loadRemoteTranslations`):
|
|
131
|
+
|
|
132
|
+
| Opção | Tipo | Padrão | Descrição |
|
|
133
|
+
| ------------ | -------------------------- | -------------- | ------------------------------------------------------------------------- |
|
|
134
|
+
| `baseUrl` | `string` | — (obrigatório) | URL base dos JSON, sem barra final. Busca `${baseUrl}/${idioma}.json`. |
|
|
135
|
+
| `version` | `string` | `undefined` | Tag de versão (`?v=`) para _cache-busting_ manual (requer CloudFront com query string na chave de cache). |
|
|
136
|
+
| `timeoutMs` | `number` | `5000` | Aborta o request após esse tempo (o boot não trava se a AWS demorar). |
|
|
137
|
+
| `fetchImpl` | `typeof fetch` | `globalThis.fetch` | `fetch` customizado (testes/SSR). |
|
|
138
|
+
| `onError` | `(error: unknown) => void` | `undefined` | Notificação de erro de fetch/parse (não-fatal; o _fallback_ é usado). |
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Cache e revalidação
|
|
143
|
+
|
|
144
|
+
Estratégia _stale-while-revalidate_:
|
|
145
|
+
|
|
146
|
+
- Cache em `localStorage`, chave `i18n.cache.<idioma>` (apenas o idioma ativo).
|
|
147
|
+
- **1º acesso:** aguarda o fetch; em falha, usa o embutido.
|
|
148
|
+
- **Acessos seguintes:** aplica o cache **na hora** (boot instantâneo) e revalida
|
|
149
|
+
em segundo plano. Se o conteúdo mudou, o cache é atualizado e **a nova versão
|
|
150
|
+
entra no próximo reload**.
|
|
151
|
+
|
|
152
|
+
O request é um **GET simples** (sem cabeçalhos customizados) com `cache:
|
|
153
|
+
"no-cache"`: a revalidação contra o CDN é feita pelo próprio browser via
|
|
154
|
+
`ETag`/`Last-Modified`, de forma transparente. Isso evita _preflight_ CORS — o
|
|
155
|
+
servidor só precisa do cabeçalho `Access-Control-Allow-Origin`.
|
|
156
|
+
|
|
157
|
+
Cadeia de _fallback_ em qualquer falha: `cache → catálogo embutido` (nunca a
|
|
158
|
+
chave crua).
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Arquivos de tradução na AWS
|
|
163
|
+
|
|
164
|
+
Um arquivo JSON **por idioma**, contendo o mapa achatado já mesclado de todos os
|
|
165
|
+
módulos:
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
${baseUrl}/pt-BR.json
|
|
169
|
+
${baseUrl}/en.json
|
|
170
|
+
${baseUrl}/es.json
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Formato (mesmo shape consumido pelo `loadTranslations()`):
|
|
174
|
+
|
|
175
|
+
```json
|
|
176
|
+
{
|
|
177
|
+
"common.cancel": "Cancelar",
|
|
178
|
+
"common.close": "Fechar",
|
|
179
|
+
"home.title": "Painel"
|
|
180
|
+
}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## Gerar/atualizar os JSON
|
|
186
|
+
|
|
187
|
+
O script de export gera os arquivos a partir dos catálogos embutidos. Use para
|
|
188
|
+
**semear** o conteúdo inicial na AWS e para manter o _fallback_ embutido
|
|
189
|
+
sincronizado a cada release.
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
npm run export:i18n
|
|
193
|
+
# escreve dist/i18n-remote/{pt-BR,en,es}.json
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Processo de hotfix de termo (sem republicar)
|
|
199
|
+
|
|
200
|
+
1. Edite o termo/acentuação diretamente no JSON do idioma na AWS (ou ajuste só as
|
|
201
|
+
chaves alteradas — arquivos parciais são suportados).
|
|
202
|
+
2. Faça upload para o S3.
|
|
203
|
+
3. Invalide o cache do CloudFront **ou** confie no `ETag` + `Cache-Control` curto
|
|
204
|
+
(a revalidação aplica a mudança no próximo reload dos usuários).
|
|
205
|
+
|
|
206
|
+
Nenhuma publicação de versão da lib nem redeploy das aplicações é necessária.
|
|
207
|
+
|
|
208
|
+
> Os catálogos `*.ts` embutidos seguem como _fallback_ (último-bom-conhecido).
|
|
209
|
+
> Para mantê-los alinhados com a AWS, rode `npm run export:i18n` periodicamente e
|
|
210
|
+
> publique uma release quando quiser atualizar o _fallback_.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Requisitos de infraestrutura (AWS)
|
|
215
|
+
|
|
216
|
+
- **S3** (com ou sem CloudFront) servindo `/i18n/{idioma}.json` por ambiente.
|
|
217
|
+
- **CORS (obrigatório):** basta `Access-Control-Allow-Origin` liberando as origens
|
|
218
|
+
das aplicações no GET (não há _preflight_, pois o request é simples). Bucket
|
|
219
|
+
público **não** dispensa CORS — sem ele o browser bloqueia a leitura via `fetch`.
|
|
220
|
+
Ver config de exemplo em [`examples/aws/s3-cors.json`](../../examples/aws/s3-cors.json).
|
|
221
|
+
- **`ETag`** (o S3 já envia) para a revalidação condicional do browser funcionar.
|
|
222
|
+
- **Propagação de hotfix:**
|
|
223
|
+
- **S3 direto (sem CDN):** a alteração é **imediata** no próximo reload.
|
|
224
|
+
- **Via CloudFront:** use `Cache-Control` curto (ex.: `max-age=300`) **ou
|
|
225
|
+
invalide** o caminho a cada hotfix — senão o edge serve a versão antiga até a
|
|
226
|
+
TTL padrão (24h).
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## Outras APIs
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import {
|
|
234
|
+
// Idioma
|
|
235
|
+
getStoredAppLanguage,
|
|
236
|
+
persistAppLanguage,
|
|
237
|
+
applyDocumentLanguage,
|
|
238
|
+
getAngularLocale,
|
|
239
|
+
getIntlLocale,
|
|
240
|
+
resolveAppLanguage,
|
|
241
|
+
APP_LANGUAGE_OPTIONS,
|
|
242
|
+
DEFAULT_APP_LANGUAGE,
|
|
243
|
+
|
|
244
|
+
// Textos de UI (validações, paginador, etc.)
|
|
245
|
+
getMapaUiTexts,
|
|
246
|
+
applyPaginatorIntl,
|
|
247
|
+
} from "mapa-frontend-i18n";
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
`getMapaUiTexts(language)` retorna textos de UI reutilizáveis (filtros, tabela,
|
|
251
|
+
validações). Alguns valores são **funções** (paginador e validações com
|
|
252
|
+
interpolação) e permanecem no código da lib — não são externalizados para JSON.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
## Idiomas suportados
|
|
257
|
+
|
|
258
|
+
| Código | Idioma | Padrão |
|
|
259
|
+
| ------- | ---------- | ------ |
|
|
260
|
+
| `pt-BR` | Português | ✅ (fonte/fallback) |
|
|
261
|
+
| `es` | Español | |
|
|
262
|
+
| `en` | English | |
|
|
263
|
+
|
|
264
|
+
O idioma escolhido é persistido em `localStorage` na chave `menu.language`.
|
|
@@ -15329,6 +15329,125 @@ function getAppLanguageOption(language) {
|
|
|
15329
15329
|
?? APP_LANGUAGE_OPTIONS[0];
|
|
15330
15330
|
}
|
|
15331
15331
|
|
|
15332
|
+
const CACHE_KEY_PREFIX = "i18n.cache.";
|
|
15333
|
+
const DEFAULT_TIMEOUT_MS = 5000;
|
|
15334
|
+
function getCacheKey(language) {
|
|
15335
|
+
return `${CACHE_KEY_PREFIX}${language}`;
|
|
15336
|
+
}
|
|
15337
|
+
function buildUrl(baseUrl, language, version) {
|
|
15338
|
+
const normalized = baseUrl.replace(/\/+$/, "");
|
|
15339
|
+
const url = `${normalized}/${language}.json`;
|
|
15340
|
+
return version ? `${url}?v=${encodeURIComponent(version)}` : url;
|
|
15341
|
+
}
|
|
15342
|
+
/** True only for a plain object whose every value is a string. */
|
|
15343
|
+
function isFlatTranslations(value) {
|
|
15344
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
15345
|
+
return false;
|
|
15346
|
+
}
|
|
15347
|
+
return Object.values(value).every((entry) => typeof entry === "string");
|
|
15348
|
+
}
|
|
15349
|
+
function resolveFetch(options) {
|
|
15350
|
+
if (options.fetchImpl) {
|
|
15351
|
+
return options.fetchImpl;
|
|
15352
|
+
}
|
|
15353
|
+
return typeof fetch === "undefined" ? undefined : fetch;
|
|
15354
|
+
}
|
|
15355
|
+
function withTimeout(timeoutMs) {
|
|
15356
|
+
if (typeof AbortController === "undefined") {
|
|
15357
|
+
return { signal: undefined, done: () => undefined };
|
|
15358
|
+
}
|
|
15359
|
+
const controller = new AbortController();
|
|
15360
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
15361
|
+
return { signal: controller.signal, done: () => clearTimeout(timer) };
|
|
15362
|
+
}
|
|
15363
|
+
/**
|
|
15364
|
+
* Reads the cached translations for a language from localStorage. Returns
|
|
15365
|
+
* `null` when there is no cache, it is unreadable, or its shape is invalid.
|
|
15366
|
+
* Safe to call during SSR (returns `null` when localStorage is unavailable).
|
|
15367
|
+
*/
|
|
15368
|
+
function readCachedTranslations(language) {
|
|
15369
|
+
if (typeof localStorage === "undefined") {
|
|
15370
|
+
return null;
|
|
15371
|
+
}
|
|
15372
|
+
try {
|
|
15373
|
+
const raw = localStorage.getItem(getCacheKey(language));
|
|
15374
|
+
if (!raw) {
|
|
15375
|
+
return null;
|
|
15376
|
+
}
|
|
15377
|
+
const parsed = JSON.parse(raw);
|
|
15378
|
+
if (!isFlatTranslations(parsed.data)) {
|
|
15379
|
+
return null;
|
|
15380
|
+
}
|
|
15381
|
+
return {
|
|
15382
|
+
version: typeof parsed.version === "string" ? parsed.version : null,
|
|
15383
|
+
data: parsed.data,
|
|
15384
|
+
};
|
|
15385
|
+
}
|
|
15386
|
+
catch {
|
|
15387
|
+
return null;
|
|
15388
|
+
}
|
|
15389
|
+
}
|
|
15390
|
+
function writeCachedTranslations(language, payload) {
|
|
15391
|
+
if (typeof localStorage === "undefined") {
|
|
15392
|
+
return;
|
|
15393
|
+
}
|
|
15394
|
+
try {
|
|
15395
|
+
localStorage.setItem(getCacheKey(language), JSON.stringify(payload));
|
|
15396
|
+
}
|
|
15397
|
+
catch {
|
|
15398
|
+
// Quota exceeded or storage disabled: ignore, the in-memory result still applies.
|
|
15399
|
+
}
|
|
15400
|
+
}
|
|
15401
|
+
/**
|
|
15402
|
+
* Fetches the remote translations for a language, updating the localStorage
|
|
15403
|
+
* cache.
|
|
15404
|
+
*
|
|
15405
|
+
* Uses a plain GET (no custom request headers) on purpose: this keeps it a
|
|
15406
|
+
* "simple" CORS request, so the only server requirement is an
|
|
15407
|
+
* `Access-Control-Allow-Origin` header — no OPTIONS preflight. Freshness is
|
|
15408
|
+
* delegated to the HTTP layer via `cache: "no-cache"`, which makes the browser
|
|
15409
|
+
* revalidate against the CDN's `ETag`/`Last-Modified` transparently (a 304 is
|
|
15410
|
+
* resolved by the browser and surfaces here as a normal 200).
|
|
15411
|
+
*
|
|
15412
|
+
* Resolution order on failure: cached data (if any), otherwise `null` so the
|
|
15413
|
+
* caller can fall back to the embedded catalogs. Never throws.
|
|
15414
|
+
*/
|
|
15415
|
+
async function loadRemoteTranslations(language, options) {
|
|
15416
|
+
const fetchImpl = resolveFetch(options);
|
|
15417
|
+
if (!fetchImpl || !options.baseUrl) {
|
|
15418
|
+
return null;
|
|
15419
|
+
}
|
|
15420
|
+
const cached = readCachedTranslations(language);
|
|
15421
|
+
const url = buildUrl(options.baseUrl, language, options.version);
|
|
15422
|
+
const { signal, done } = withTimeout(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
15423
|
+
try {
|
|
15424
|
+
const response = await fetchImpl(url, {
|
|
15425
|
+
cache: "no-cache",
|
|
15426
|
+
signal,
|
|
15427
|
+
});
|
|
15428
|
+
if (!response.ok) {
|
|
15429
|
+
throw new Error(`Failed to load translations: HTTP ${response.status}`);
|
|
15430
|
+
}
|
|
15431
|
+
const data = await response.json();
|
|
15432
|
+
if (!isFlatTranslations(data)) {
|
|
15433
|
+
throw new Error("Remote translations payload is not a flat string map");
|
|
15434
|
+
}
|
|
15435
|
+
writeCachedTranslations(language, {
|
|
15436
|
+
version: options.version ?? null,
|
|
15437
|
+
fetchedAt: Date.now(),
|
|
15438
|
+
data,
|
|
15439
|
+
});
|
|
15440
|
+
return data;
|
|
15441
|
+
}
|
|
15442
|
+
catch (error) {
|
|
15443
|
+
options.onError?.(error);
|
|
15444
|
+
return cached?.data ?? null;
|
|
15445
|
+
}
|
|
15446
|
+
finally {
|
|
15447
|
+
done();
|
|
15448
|
+
}
|
|
15449
|
+
}
|
|
15450
|
+
|
|
15332
15451
|
function getStoredAppLanguage() {
|
|
15333
15452
|
if (typeof window === "undefined") {
|
|
15334
15453
|
return DEFAULT_APP_LANGUAGE;
|
|
@@ -15365,6 +15484,64 @@ function initializeAppLanguage(options = {}) {
|
|
|
15365
15484
|
}
|
|
15366
15485
|
return language;
|
|
15367
15486
|
}
|
|
15487
|
+
/**
|
|
15488
|
+
* Merges the embedded (build-time) catalog for a language with an optional
|
|
15489
|
+
* remote map and hands the result to `@angular/localize`. The remote entries
|
|
15490
|
+
* override the embedded ones, while any key missing remotely still resolves
|
|
15491
|
+
* from the embedded fallback — so partial remote files are safe.
|
|
15492
|
+
*/
|
|
15493
|
+
function applyTranslations(language, remote) {
|
|
15494
|
+
const merged = {
|
|
15495
|
+
...(ANGULAR_RUNTIME_TRANSLATIONS[language] ?? {}),
|
|
15496
|
+
...(remote ?? {}),
|
|
15497
|
+
};
|
|
15498
|
+
if (Object.keys(merged).length > 0) {
|
|
15499
|
+
loadTranslations(merged);
|
|
15500
|
+
}
|
|
15501
|
+
}
|
|
15502
|
+
/**
|
|
15503
|
+
* Initializes translations by loading them from the remote (AWS) JSON files,
|
|
15504
|
+
* with the embedded catalogs as a fallback. MUST be awaited before the host
|
|
15505
|
+
* application bootstraps, because `$localize` resolves messages at evaluation
|
|
15506
|
+
* time from the global map populated here.
|
|
15507
|
+
*
|
|
15508
|
+
* Behaviour:
|
|
15509
|
+
* - With a local cache: applies the cached copy immediately (instant boot) and
|
|
15510
|
+
* revalidates in the background; an updated copy takes effect on the next reload.
|
|
15511
|
+
* - Without a cache: awaits the remote fetch and, on any failure, falls back to
|
|
15512
|
+
* the embedded catalogs (never the raw keys).
|
|
15513
|
+
*/
|
|
15514
|
+
async function initializeAppLanguageAsync(options) {
|
|
15515
|
+
const language = getStoredAppLanguage();
|
|
15516
|
+
if (options.clearExistingTranslations) {
|
|
15517
|
+
clearTranslations();
|
|
15518
|
+
}
|
|
15519
|
+
applyDocumentLanguage(language);
|
|
15520
|
+
const cached = readCachedTranslations(language);
|
|
15521
|
+
if (cached) {
|
|
15522
|
+
applyTranslations(language, cached.data);
|
|
15523
|
+
// Fire-and-forget revalidation; the refreshed cache applies on next reload.
|
|
15524
|
+
void loadRemoteTranslations(language, options).catch(() => undefined);
|
|
15525
|
+
return language;
|
|
15526
|
+
}
|
|
15527
|
+
const remote = await loadRemoteTranslations(language, options);
|
|
15528
|
+
applyTranslations(language, remote);
|
|
15529
|
+
return language;
|
|
15530
|
+
}
|
|
15531
|
+
/**
|
|
15532
|
+
* Initializes translations from data the caller already fetched. Intended for
|
|
15533
|
+
* micro-frontend setups where a host fetches the remote translations once and
|
|
15534
|
+
* shares them with each MFE, avoiding one network request per MFE. The data is
|
|
15535
|
+
* merged over the embedded fallback, like {@link initializeAppLanguageAsync}.
|
|
15536
|
+
*/
|
|
15537
|
+
function initializeAppLanguageFromData(language, remote, options = {}) {
|
|
15538
|
+
if (options.clearExistingTranslations) {
|
|
15539
|
+
clearTranslations();
|
|
15540
|
+
}
|
|
15541
|
+
applyDocumentLanguage(language);
|
|
15542
|
+
applyTranslations(language, remote);
|
|
15543
|
+
return language;
|
|
15544
|
+
}
|
|
15368
15545
|
|
|
15369
15546
|
const PAGINATOR_COPY_BY_LANGUAGE = {
|
|
15370
15547
|
"pt-BR": {
|
|
@@ -15629,5 +15806,5 @@ function getMapaUiTexts(language) {
|
|
|
15629
15806
|
* Generated bundle index. Do not edit.
|
|
15630
15807
|
*/
|
|
15631
15808
|
|
|
15632
|
-
export { ANGULAR_RUNTIME_TRANSLATIONS, APP_LANGUAGE_OPTIONS, APP_LANGUAGE_STORAGE_KEY, DEFAULT_APP_LANGUAGE, MAPA_UI_TEXTS_PT_BR, MA_TRANSLATIONS, MCA_TRANSLATIONS, MENU_TRANSLATIONS, MF_TRANSLATIONS, MGA_TRANSLATIONS, MGC_TRANSLATIONS, MO_TRANSLATIONS, MP_TRANSLATIONS, MV_TRANSLATIONS, applyDocumentLanguage, applyPaginatorIntl, formatPaginatorRange, formatPaginatorShowingRange, getAngularLocale, getAppLanguageOption, getIntlLocale, getMapaUiTexts, getPaginatorNavigationLabels, getStoredAppLanguage, initializeAppLanguage, isAppLanguage, persistAppLanguage, resolveAppLanguage };
|
|
15809
|
+
export { ANGULAR_RUNTIME_TRANSLATIONS, APP_LANGUAGE_OPTIONS, APP_LANGUAGE_STORAGE_KEY, DEFAULT_APP_LANGUAGE, MAPA_UI_TEXTS_PT_BR, MA_TRANSLATIONS, MCA_TRANSLATIONS, MENU_TRANSLATIONS, MF_TRANSLATIONS, MGA_TRANSLATIONS, MGC_TRANSLATIONS, MO_TRANSLATIONS, MP_TRANSLATIONS, MV_TRANSLATIONS, applyDocumentLanguage, applyPaginatorIntl, formatPaginatorRange, formatPaginatorShowingRange, getAngularLocale, getAppLanguageOption, getIntlLocale, getMapaUiTexts, getPaginatorNavigationLabels, getStoredAppLanguage, initializeAppLanguage, initializeAppLanguageAsync, initializeAppLanguageFromData, isAppLanguage, loadRemoteTranslations, persistAppLanguage, readCachedTranslations, resolveAppLanguage };
|
|
15633
15810
|
//# sourceMappingURL=mapa-frontend-i18n.mjs.map
|