feat(i18n): översätt kvarvarande vyer + härda vakten (audit-backlog)
- API: översatt title/displayName/toName läggs nu bredvid Sv-fälten i favoriter,
receptvarianter, /scaled, skapar-profiler, topplistor, memory-impact,
substitutions — samt de denormaliserade titlarna (min dag, historik, matlådor,
matlåde-förslag, veckoplan) via nullable recipeId med svensk fallback.
10 endpoints, batchade resolvers (ett anrop per endpoint).
- Mobil: konsumerar de nya fälten med ?? Sv-fallback (swap-meal, sparade recept,
varianter, min dag, logg, matlådor, veckoplan, inköpslista). Hårdkodade
strängar -> t() (kitchen, scan-review, register, recept protein/Skapat av);
decimalkomma -> Intl.NumberFormat. Allergen-etiketter -> t() (+5 nya nycklar).
11 nya nycklar i alla 12 språk.
- i18n-vakt härdad: fångar nu hårdkodad svenska i prop={`...`}-mallliteraler
(blind fläck förr). Verifierat att den fäller men inte ger falska positiv.
- whySv var redan lokaliserad (buildWhy med språktagg) - orörd.
- typecheck grönt (alla paket), vakt grön (603 nycklar).
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -106,6 +106,10 @@ const POS =
|
||||
/(?:label|placeholder|title|text|header|message)\s*[=:]\s*(["'`])((?:(?!\1).)*[A-Za-zÅÄÖåäö]{2,}(?:(?!\1).)*)\1/g;
|
||||
const ALERT =
|
||||
/(?:Alert\.alert|setError|EmptyState\s+text=)\s*\(?\s*(["'`])((?:(?!\1).)*[A-Za-zÅÄÖåäö]{2,}(?:(?!\1).)*)\1/g;
|
||||
// prop={`…`} – mall-literal i JSX-UTTRYCK. POS ser inte {…}, så no-diakritisk
|
||||
// svenska (»Skapat av ${x}«) slank förr igenom. Granska den literala resten.
|
||||
const PROP_EXPR =
|
||||
/(?:label|placeholder|title|text|header|message)\s*=\s*\{\s*`((?:[^`\\]|\\.)*)`\s*\}/g;
|
||||
// JSX-text: >Svensk text< (fångar diakriter i textnoder)
|
||||
const JSXTEXT = />\s*([^<>{}\n]*[åäöÅÄÖ][^<>{}\n]*?)\s*</g;
|
||||
|
||||
@@ -132,10 +136,20 @@ for (const file of files) {
|
||||
let mm;
|
||||
while ((mm = re.exec(line))) {
|
||||
const val = mm[2];
|
||||
if (val.includes("${")) continue; // ren interpolationsdel
|
||||
if (!allowed(val)) hits.add(val);
|
||||
// Mallsträngar granskas nu på den LITERALA resten (blind fläck förr –
|
||||
// `label={\`Skapat av ${namn}\`}` slank igenom hela). Strippa ${…} och
|
||||
// se om ord blir kvar; bara emoji/tal/enheter kvar = ok.
|
||||
const bare = val.replace(/\$\{[^}]*\}/g, " ");
|
||||
if (!/[A-Za-zÅÄÖåäö]{2,}/.test(bare)) continue;
|
||||
if (!allowed(bare)) hits.add(val);
|
||||
}
|
||||
}
|
||||
PROP_EXPR.lastIndex = 0;
|
||||
let pm;
|
||||
while ((pm = PROP_EXPR.exec(line))) {
|
||||
const bare = pm[1].replace(/\$\{[^}]*\}/g, " ");
|
||||
if (/[A-Za-zÅÄÖåäö]{2,}/.test(bare) && !allowed(bare)) hits.add(pm[1]);
|
||||
}
|
||||
JSXTEXT.lastIndex = 0;
|
||||
let jm;
|
||||
while ((jm = JSXTEXT.exec(line))) {
|
||||
|
||||
Reference in New Issue
Block a user