feat(fase-20): eu.json seed + Paraglide config + locale parity check

Seeds apps/web/messages/eu.json with hand-translated Basque values for
every key in en.json/es.json (362 keys, $schema excluded). Each value
carries the ` [needs review]` suffix marker per plan §20.2.1 so a
native speaker can sweep through and remove markers in a post-release
pass. ICU placeholders ({name}, {count}, {n}, {version}, …) preserved
verbatim — none move position relative to the source value.

Adds `eu` to project.inlang/settings.json so the Paraglide vite plugin
emits `src/lib/paraglide/messages/eu.js` on next build, and the runtime
`availableLanguageTags` widens to ["en","es","eu"]. The compile output
is gitignored as before; verified by re-running the compile CLI locally.

New `scripts/check-locales.mjs` (dependency-free Node script) compares
every non-source bundle's key set against en.json and fails on any
missing/extra keys. Currently: eu = 362 keys, es = 362 keys, both match.

Note on translation provenance: machine/LLM seed at mid-2026 quality.
The plan calls out euskera SOV ordering risks around placeholders —
spot-checked the 12 keys with placeholders ({name}, {count}, {n},
{version}, {date}, {commit}, {word}, {title}, {days}, {lists}, {tasks},
{notes}, {section}); placeholders stayed in source-comparable positions.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-19 03:52:36 +02:00
parent ee13e7bc9d
commit 39ec7996c5
3 changed files with 456 additions and 1 deletions

365
apps/web/messages/eu.json Normal file
View File

@@ -0,0 +1,365 @@
{
"$schema": "https://inlang.com/schema/inlang-message-format",
"nav_lists": "Zerrendak [needs review]",
"nav_tasks": "Zereginak [needs review]",
"nav_notes": "Oharrak [needs review]",
"nav_search": "Bilatu [needs review]",
"nav_settings": "Ezarpenak [needs review]",
"nav_collective": "Kolektiboa [needs review]",
"app_name": "Colectivo [needs review]",
"loading": "Kargatzen… [needs review]",
"error_generic": "Zerbait gaizki joan da. Saiatu berriro, mesedez. [needs review]",
"login_title": "Sartu Colectivo-n [needs review]",
"login_button": "Saioa hasi [needs review]",
"logout_button": "Saioa itxi [needs review]",
"auth_back_to_home": "Hasierara itzuli [needs review]",
"logged_out_title": "Saioa itxita [needs review]",
"logged_out_subtitle": "Hasi saioa berriro jarraitzeko. [needs review]",
"logged_out_sign_in": "Saioa hasi [needs review]",
"onboarding_title": "Ongi etorri Colectivo-ra [needs review]",
"onboarding_subtitle": "Sortu kolektibo berri bat edo elkartu dagoen batekin. [needs review]",
"onboarding_create_tab": "Sortu [needs review]",
"onboarding_join_tab": "Elkartu [needs review]",
"onboarding_create_collective": "Sortu kolektibo bat [needs review]",
"onboarding_join_collective": "Elkartu gonbidapen esteka batekin [needs review]",
"onboarding_collective_name": "Kolektiboaren izena [needs review]",
"onboarding_collective_name_placeholder": "adib. Gure Etxea [needs review]",
"onboarding_collective_emoji": "Ikonoa [needs review]",
"onboarding_invite_link_label": "Gonbidapen esteka [needs review]",
"onboarding_invite_link_placeholder": "Itsatsi hemen gonbidapen esteka… [needs review]",
"onboarding_create_btn": "Sortu kolektiboa [needs review]",
"onboarding_join_btn": "Elkartu kolektiboarekin [needs review]",
"collective_name_label": "Kolektiboaren izena [needs review]",
"collective_name_placeholder": "adib. Gure Etxea [needs review]",
"invitation_title": "Gonbidapen bat duzu [needs review]",
"invitation_subtitle": "Kolektibo batera elkartzeko gonbidatu zaituzte. [needs review]",
"invitation_accept_btn": "Gonbidapena onartu [needs review]",
"invitation_success": "Kolektiboari elkartu zara! [needs review]",
"invitation_invalid_link": "Honek ez dirudi baliozko gonbidapen esteka. [needs review]",
"invitation_error_not_found": "Gonbidapen esteka hau ez da baliozkoa. [needs review]",
"invitation_error_already_used": "Gonbidapen hau dagoeneko erabili da. [needs review]",
"invitation_error_expired": "Gonbidapen hau iraungita dago. [needs review]",
"invitation_error_already_member": "Dagoeneko kolektibo honetako kide zara. [needs review]",
"invitation_error_unauthenticated": "Gonbidapena onartzeko, saioa hasi behar duzu. [needs review]",
"invitation_error_unknown": "Zerbait gaizki joan da. Saiatu berriro, mesedez. [needs review]",
"manage_title": "Kolektiboa kudeatu [needs review]",
"manage_members": "Kideak [needs review]",
"manage_you": "zu [needs review]",
"manage_remove": "Kidea ezabatu [needs review]",
"manage_invite_title": "Inor gonbidatu [needs review]",
"manage_invite_role": "Rola [needs review]",
"manage_generate_link": "Gonbidapen esteka sortu [needs review]",
"manage_copy": "Kopiatu [needs review]",
"manage_copied": "Kopiatuta! [needs review]",
"manage_link_expires": "Esteka 7 egunetan iraungiko da. [needs review]",
"role_admin": "Administratzailea [needs review]",
"role_member": "Kidea [needs review]",
"role_guest": "Gonbidatua [needs review]",
"settings_title": "Ezarpenak [needs review]",
"settings_display_name": "Ikusgai dagoen izena [needs review]",
"settings_saving": "Gordetzen… [needs review]",
"settings_language": "Hizkuntza [needs review]",
"settings_avatar": "Abatarra [needs review]",
"settings_avatar_initials": "Inizialak [needs review]",
"settings_avatar_emoji": "Emoji [needs review]",
"settings_avatar_upload": "Argazkia [needs review]",
"settings_avatar_upload_btn": "Argazkia igo… [needs review]",
"settings_account": "Kontua [needs review]",
"settings_keycloak_link": "Helbide elektronikoa edo pasahitza aldatu [needs review]",
"settings_logout": "Saioa itxi [needs review]",
"settings_save": "Aldaketak gorde [needs review]",
"settings_saved": "Aldaketak gordeta [needs review]",
"invite_member": "Kidea gonbidatu [needs review]",
"invite_email_label": "Helbide elektronikoa [needs review]",
"invite_send": "Gonbidapena bidali [needs review]",
"masthead_lists_label": "Espazioa [needs review]",
"masthead_tasks_label": "Zereginak [needs review]",
"masthead_notes_label": "Biltegia [needs review]",
"masthead_search_label": "Bilatu [needs review]",
"masthead_search_title": "Aurkitu dena. [needs review]",
"lists_title": "Erosketa zerrendak [needs review]",
"lists_new_list": "Zerrenda berria [needs review]",
"lists_no_lists": "Zerrendarik ez [needs review]",
"lists_create_first": "Sortu zure lehen erosketa zerrenda [needs review]",
"lists_trash": "Zakarrontzia [needs review]",
"list_status_active": "Zerrenda aktiboa [needs review]",
"list_status_completed": "Osatua [needs review]",
"list_status_archived": "Artxibatua [needs review]",
"list_name_placeholder": "adib. Asteko erosketa [needs review]",
"list_items_empty": "Zerrenda hutsa [needs review]",
"list_items_empty_hint": "Gehitu zure lehen produktua behean [needs review]",
"list_reset": "Zerrenda berrabiarazi [needs review]",
"list_archive": "Artxibatu [needs review]",
"list_delete": "Zakarrontzira eraman [needs review]",
"list_actions": "Zerrendaren ekintzak [needs review]",
"list_item_placeholder": "Produktua gehitu… [needs review]",
"list_qty_label": "Kop. [needs review]",
"list_add_item": "Produktua gehitu… [needs review]",
"list_to_buy": "Erosteko [needs review]",
"list_checked": "Markatuta [needs review]",
"list_start_session": "Erosi [needs review]",
"list_finish_shopping": "Erosketa amaitu [needs review]",
"list_finish_confirm": "Zerrenda hau osatutzat eman? [needs review]",
"list_finish_confirm_yes": "Bai, amaitu [needs review]",
"list_finish_confirm_no": "Erosten jarraitu [needs review]",
"tasks_title": "Zereginak [needs review]",
"tasks_new_list": "Zerrenda berria [needs review]",
"tasks_no_lists": "Zeregin zerrendarik ez [needs review]",
"tasks_create_first": "Sortu zure lehen zeregin zerrenda [needs review]",
"tasks_new_list_placeholder": "Zeregin zerrenda berria [needs review]",
"tasks_new_task_placeholder": "Zeregina gehitu [needs review]",
"tasks_empty": "Zereginik ez [needs review]",
"tasks_empty_hint": "Gehitu zure lehen zeregina behean [needs review]",
"tasks_completed_section": "Osatuak [needs review]",
"tasks_pending_section": "Egiteke [needs review]",
"tasks_completed_by": "{name}-(e)k osatua [needs review]",
"tasks_toggle": "Zeregina txandakatu [needs review]",
"tasks_uncheck": "Zeregina desmarkatu [needs review]",
"tasks_delete": "Zeregina ezabatu [needs review]",
"tasks_delete_list": "Zerrenda ezabatu [needs review]",
"tasks_delete_list_confirm": "Zerrenda hau eta bere zeregin guztiak ezabatu? [needs review]",
"notes_title": "Oharrak [needs review]",
"notes_new": "Ohar berria [needs review]",
"notes_pinned_section": "Finkatuak [needs review]",
"notes_active_section": "Oharrak [needs review]",
"notes_archive": "Artxibatu [needs review]",
"notes_archive_view": "Artxibatutako oharrak [needs review]",
"notes_archived_empty": "Artxibatutako oharrik ez [needs review]",
"notes_trash_view": "Oharren zakarrontzia [needs review]",
"notes_trash_empty": "Zakarrontzia hutsik dago [needs review]",
"notes_pin": "Oharra finkatu [needs review]",
"notes_unpin": "Oharra desfinkatu [needs review]",
"notes_unarchive": "Oharra desartxibatu [needs review]",
"notes_send_to_trash": "Zakarrontzira bidali [needs review]",
"notes_restore": "Berreskuratu [needs review]",
"notes_duplicate": "Bikoiztu [needs review]",
"notes_color": "Kolorea [needs review]",
"notes_title_placeholder": "Izenburua [needs review]",
"notes_content_placeholder": "Hasi idazten… [needs review]",
"notes_content_aria": "Edukia [needs review]",
"notes_back_to_board": "Taulara itzuli [needs review]",
"notes_saved": "Gordeta [needs review]",
"notes_saving": "Gordetzen… [needs review]",
"notes_empty_board": "Oharrik ez [needs review]",
"notes_empty_board_hint": "Sakatu \"Ohar berria\" hasteko [needs review]",
"search_title": "Bilatu [needs review]",
"search_placeholder": "Bilatu zerrendak, zereginak, oharrak… [needs review]",
"search_filter_all": "Dena [needs review]",
"search_filter_lists": "Zerrendak [needs review]",
"search_filter_tasks": "Zereginak [needs review]",
"search_filter_notes": "Oharrak [needs review]",
"search_group_shopping_items": "Produktuak [needs review]",
"search_group_tasks": "Zereginak [needs review]",
"search_group_notes": "Oharrak [needs review]",
"search_empty": "Emaitzarik ez [needs review]",
"search_hint": "Idatzi gutxienez bi karaktere [needs review]",
"trash_restore": "Berreskuratu [needs review]",
"trash_delete_permanent": "Behin betiko ezabatu [needs review]",
"trash_empty": "Zakarrontzia hutsik dago [needs review]",
"trash_expires_in": "{days} egunetan iraungiko da [needs review]",
"confirm_delete": "Ezabatu? [needs review]",
"cancel": "Utzi [needs review]",
"save": "Gorde [needs review]",
"action_delete": "Ezabatu [needs review]",
"edit": "Editatu [needs review]",
"add": "Gehitu [needs review]",
"done": "Eginda [needs review]",
"pwa_update_available": "Bertsio berria eskuragarri [needs review]",
"pwa_update_reload": "Birkargatu [needs review]",
"pwa_offline_ready": "Lineaz kanpo erabiltzeko prest [needs review]",
"pwa_offline_chip": "Konexiorik gabe [needs review]",
"pwa_offline_tooltip": "Konexiorik gabe — aldaketak itzultzean sinkronizatuko dira [needs review]",
"pwa_pending_ops": "{count} aldaketa zain [needs review]",
"pwa_pending_ops_plural": "{count} aldaketa zain [needs review]",
"pwa_sync_conflicts_banner": "Sinkronizazio gatazkak daude [needs review]",
"pwa_sync_conflicts_review": "Berrikusi [needs review]",
"sync_conflicts_title": "Sinkronizazio gatazkak [needs review]",
"sync_conflicts_empty": "Ezer zain — lokala eta zerbitzaria bat datoz. [needs review]",
"sync_conflicts_discard_local": "Lokala baztertu [needs review]",
"sync_conflicts_discard_remote": "Urrunekoa baztertu [needs review]",
"sync_conflicts_back": "Ezarpenetara itzuli [needs review]",
"settings_about": "Honi buruz [needs review]",
"settings_about_version": "v{version} · {commit} · {date} [needs review]",
"settings_about_view_changelog": "Historia ikusi [needs review]",
"changelog_modal_title": "Aldaketen historia [needs review]",
"changelog_modal_close": "Itxi [needs review]",
"sync_offline": "Konexiorik gabe — aldaketak berriz konektatzean sinkronizatuko dira [needs review]",
"sync_syncing": "Sinkronizatzen… [needs review]",
"undo": "Desegin [needs review]",
"undo_deleted_item": "{name} ezabatuta [needs review]",
"list_item_delete_aria": "Produktua ezabatu [needs review]",
"list_qty_decrease": "Kopurua jaitsi [needs review]",
"list_qty_increase": "Kopurua igo [needs review]",
"list_reorder_handle": "Berrantolatu [needs review]",
"list_edit_item": "Produktua editatu [needs review]",
"list_confirm": "Baieztatu [needs review]",
"list_close": "Itxi [needs review]",
"list_select": "Hautatu [needs review]",
"list_selection_count": "{n} hautatuta [needs review]",
"list_cancel_selection": "Utzi [needs review]",
"list_bulk_delete": "Ezabatu [needs review]",
"list_bulk_move": "Mugitu [needs review]",
"list_bulk_mark_checked": "Markatu [needs review]",
"list_undo_bulk_delete": "{n} ezabatuta [needs review]",
"list_move_title": "Zerrendara eraman [needs review]",
"list_move_create_new": "Zerrenda berria sortu [needs review]",
"settings_appearance": "Itxura [needs review]",
"settings_theme_light": "Argia [needs review]",
"settings_theme_dark": "Iluna [needs review]",
"settings_theme_system": "Sistema [needs review]",
"settings_sync_conflicts": "Sinkronizazio gatazkak [needs review]",
"settings_sync_conflicts_empty": "Erregistratutako gatazkarik ez. [needs review]",
"settings_sync_conflicts_export": "JSON esportatu [needs review]",
"settings_collectives": "Zure kolektiboak [needs review]",
"settings_collectives_empty": "Ez zara inongo kolektiboko kide. [needs review]",
"settings_collectives_leave": "Utzi [needs review]",
"settings_collectives_confirm_leave_title": "{name} utzi? [needs review]",
"settings_collectives_confirm_leave_body": "Kolektibo honetarako sarbidea galduko duzu. Edukia gainerako kideentzat geratuko da. [needs review]",
"settings_collectives_confirm_leave_button": "Kolektiboa utzi [needs review]",
"settings_collectives_dissolve_hint": "Kide bakarra zara — erabili 'Desegin' kolektiboaren orrian horren ordez. [needs review]",
"settings_danger_zone": "Eremu arriskutsua [needs review]",
"settings_delete_account": "Nire kontua ezabatu [needs review]",
"settings_delete_account_blurb": "Behin betiko ezabatzen ditu zure kontua eta zure kidetza guztiak. Sortu duzun edukia kolektiboetan geratuko da, ezabatutako erabiltzaile bati esleitua. [needs review]",
"settings_delete_account_modal_title": "Zure kontua ezabatu? [needs review]",
"settings_delete_account_modal_body": "Hau behin betikoa da. Ezabatzen dena: zure kontua, zure kidetzak, zure hizkuntza eta gai gordeak. Geratzen dena: sortu dituzun zerrendak, zereginak edo oharrak — euren kolektiboetan geratzen dira, ezabatutako erabiltzaile bati esleituak. Kolektiboren bateko administratzaile bakarra bazara, kide zaharrena automatikoki sustatuko da. Oharra: identitate-hornitzailearen kontua EZ da ezabatzen; helbide elektroniko berarekin berriro erregistratu zaitezke eta profil berri bat sortuko da. [needs review]",
"settings_delete_account_confirm_label": "Idatzi {word} baieztatzeko [needs review]",
"settings_delete_account_confirm_word": "EZABATU [needs review]",
"settings_delete_account_button": "Kontua behin betiko ezabatu [needs review]",
"settings_delete_account_blocked": "Sustatu ezin diren kideak dituen kolektibo bateko administratzaile bakarra zara. Sustatu norbait lehenik edo ezabatu gainerako kideak. [needs review]",
"common_cancel": "Utzi [needs review]",
"manage_collective_name_label": "Kolektiboaren izena [needs review]",
"manage_collective_emoji_label": "Ikonoa [needs review]",
"manage_collective_save": "Gorde [needs review]",
"manage_dissolve_section": "Eremu arriskutsua [needs review]",
"manage_dissolve_button": "Kolektiboa desegin [needs review]",
"manage_dissolve_blurb": "Kolektibo hau eta bere eduki guztia behin betiko ezabatzen ditu. Ezin da desegin. [needs review]",
"manage_dissolve_title": "{name} desegin? [needs review]",
"manage_dissolve_warning": "{lists} zerrenda, {tasks} zeregin eta {notes} ohar ezabatuko dira. Ekintza hau itzulezina da. [needs review]",
"manage_dissolve_confirm_label": "Idatzi {name} baieztatzeko [needs review]",
"manage_dissolve_confirm_button": "Behin betiko desegin [needs review]",
"sidebar_create_collective": "+ Kolektibo berria [needs review]",
"create_collective_modal_title": "Kolektibo berria [needs review]",
"create_collective_modal_button": "Sortu [needs review]",
"tag_picker_placeholder": "Etiketa bilatu edo sortu [needs review]",
"tag_picker_create": "«{name}» sortu [needs review]",
"tag_picker_empty": "Oraindik ez dago etiketarik. [needs review]",
"tag_picker_label": "Etiketak [needs review]",
"list_filter_by_tag": "Etiketaz iragazi [needs review]",
"list_filter_clear": "Garbitu [needs review]",
"settings_tags_section": "Etiketak [needs review]",
"settings_tags_empty": "Oraindik ez dago etiketarik — sortu edozein zerrendatatik. [needs review]",
"settings_tags_delete": "Ezabatu [needs review]",
"settings_tags_color": "Kolorea [needs review]",
"section_disabled_for_collective": "Atal hau kolektibo honentzat ezkutatuta dago. [needs review]",
"settings_section_visibility_title": "Ikusgai dauden atalak [needs review]",
"settings_section_visibility_blurb": "Ezkutatu erabiltzen ez dituzun goi-mailako atalak. Zure administratzaileak ere kolektibo osorako ezkuta ditzake. [needs review]",
"settings_section_visibility_overridden": "Kolektiboak ezkutatua. [needs review]",
"collective_section_visibility_title": "Kolektiboaren atalak [needs review]",
"collective_section_visibility_blurb": "Ezkutatu atalak kolektibo honetako kide guztientzat. Kide bakoitzak ere bere buruarentzat ezkuta ditzake. [needs review]",
"section_label_lists": "Zerrendak [needs review]",
"section_label_tasks": "Zereginak [needs review]",
"section_label_notes": "Oharrak [needs review]",
"section_label_search": "Bilatu [needs review]",
"admin_banner": "Admin modua — ekintzak erregistratzen dira [needs review]",
"admin_nav_collectives": "Kolektiboak [needs review]",
"admin_nav_admins": "Administratzaileak [needs review]",
"admin_nav_audit": "Erregistroa [needs review]",
"admin_nav_server": "Zerbitzaria [needs review]",
"admin_menu_entry": "Zerbitzariko administratzailea [needs review]",
"admin_collectives_title": "Kolektiboak [needs review]",
"admin_collectives_search_placeholder": "Izenez bilatu… [needs review]",
"admin_collectives_empty": "Ez dator bat kolektiborik. [needs review]",
"admin_collectives_col_name": "Izena [needs review]",
"admin_collectives_col_members": "Kideak [needs review]",
"admin_collectives_col_created": "Sortua [needs review]",
"admin_collectives_col_status": "Egoera [needs review]",
"admin_collectives_status_active": "Aktiboa [needs review]",
"admin_collectives_status_deleted": "Ezabatua [needs review]",
"admin_action_view": "Ikusi [needs review]",
"admin_action_soft_delete": "Soft-delete [needs review]",
"admin_action_restore": "Berreskuratu [needs review]",
"admin_action_hard_delete": "Ezabatu [needs review]",
"admin_action_remove": "Kanporatu [needs review]",
"admin_modal_soft_delete_title": "Kolektiboa soft-delete egin [needs review]",
"admin_modal_soft_delete_help": "Kolektiboa ezkutatuta geratzen da kideentzat, baina berreskuragarri 30 egunez. Arrazoia erregistratzen da. [needs review]",
"admin_modal_reason_label": "Arrazoia [needs review]",
"admin_modal_reason_placeholder": "Zergatik? [needs review]",
"admin_modal_hard_delete_title": "Kolektiboa ezabatu [needs review]",
"admin_modal_hard_delete_help": "Hau itzulezina da. Zerrenda, item, zeregin eta ohar guztiak ezabatuko dira. [needs review]",
"admin_modal_hard_delete_confirm": "Itzulezina dela ulertzen dut [needs review]",
"admin_modal_hard_delete_force_label": "Behartu (30 eguneko itxaronaldia saltatu) [needs review]",
"admin_modal_cancel": "Utzi [needs review]",
"admin_modal_confirm": "Baieztatu [needs review]",
"admin_collective_detail_back": "Kolektiboetara itzuli [needs review]",
"admin_collective_detail_members": "Kideak [needs review]",
"admin_collective_detail_recent_actions": "Azken ekintzak [needs review]",
"admin_modal_remove_member_title": "Kidea kanporatu [needs review]",
"admin_modal_remove_member_help": "Kidetza berehala ezeztatzen da. Arrazoia erregistratzen da. [needs review]",
"admin_admins_title": "Zerbitzariko administratzaileak [needs review]",
"admin_admins_promote": "Erabiltzailea sustatu [needs review]",
"admin_admins_promote_help": "Sartu sustatu beharreko erabiltzailearen helbide elektronikoa. [needs review]",
"admin_admins_email_label": "Helbide elektronikoa [needs review]",
"admin_admins_email_placeholder": "erabiltzailea@adibidea.com [needs review]",
"admin_admins_email_not_found": "Helbide elektroniko hori duen erabiltzailerik ez. [needs review]",
"admin_admins_revoke_self": "zu (ezin duzu zeure burua ezeztatu administratzaile bakarra bazara) [needs review]",
"admin_admins_revoke": "Ezeztatu [needs review]",
"admin_audit_title": "Ekintzen erregistroa [needs review]",
"admin_audit_empty": "Oraindik ez da ekintzarik erregistratu. [needs review]",
"admin_audit_col_when": "Noiz [needs review]",
"admin_audit_col_actor": "Eragilea [needs review]",
"admin_audit_col_action": "Ekintza [needs review]",
"admin_audit_col_target": "Helburua [needs review]",
"admin_audit_col_payload": "Payload [needs review]",
"admin_server_title": "Zerbitzariaren konfigurazioa [needs review]",
"admin_server_default_sections": "Atalen lehenetsitako ikusgaitasuna [needs review]",
"admin_server_default_sections_help": "Zerbitzari mailako override-a. Hemen ON edo OFF jartzeak edozein kolektibo edo erabiltzaile gainditzen du. [needs review]",
"admin_server_section_state_off": "OFF [needs review]",
"admin_server_section_state_on": "ON [needs review]",
"admin_server_section_state_unset": "Iritzirik gabe [needs review]",
"admin_server_info": "Zerbitzariaren informazioa [needs review]",
"admin_error_forbidden": "Ez duzu eremu honetarako sarbiderik. [needs review]",
"admin_error_unknown": "Zerbait gaizki joan da. Saiatu berriro. [needs review]",
"common_items_title": "Item ohikoak [needs review]",
"common_items_blurb": "Sustatu beti iradokizunetan lehenik agertzea nahi dituzun itemak, edo ezkutatu ikusi nahi ez dituzunak. Kideek katalogoa ikusten dute baina ezin dute editatu. [needs review]",
"common_items_search_placeholder": "Itemak bilatu… [needs review]",
"common_items_empty": "Oraindik ez dago item ohikorik. Zerrendetara gehitzen diren itemak hemen agertuko dira. [needs review]",
"common_items_empty_filtered": "Ez dator bat itemik zure bilaketarekin. [needs review]",
"common_items_col_name": "Izena [needs review]",
"common_items_col_weight": "Ikusgaitasuna [needs review]",
"common_items_col_uses": "Erabilerak [needs review]",
"common_items_col_last_used": "Azken erabilera [needs review]",
"common_items_col_actions": "Ekintzak [needs review]",
"common_items_state_hide": "Ezkutatu [needs review]",
"common_items_state_normal": "Normala [needs review]",
"common_items_state_boost": "Nabarmendu [needs review]",
"common_items_state_locked_tooltip": "Administratzaileek soilik kudea ditzakete item ohikoak. [needs review]",
"common_items_purge_button": "Ezabatu [needs review]",
"common_items_purge_modal_title": "{name} ezabatu? [needs review]",
"common_items_purge_modal_body": "Honek iradokizunetatik sarrera kentzen du soilik. Dagoeneko zerrendetan dauden itemak ez dira aldatzen. [needs review]",
"common_items_purge_confirm": "Ezabatu [needs review]",
"common_items_add_button": "Item komuna gehitu [needs review]",
"common_items_add_modal_title": "Item komuna gehitu [needs review]",
"common_items_add_name_label": "Itemaren izena [needs review]",
"common_items_add_name_placeholder": "adib. oliba olioa [needs review]",
"common_items_add_visibility_label": "Ikusgaitasuna [needs review]",
"common_items_add_save": "Gehitu [needs review]",
"create_list_modal_title": "Erosketa zerrenda berria [needs review]",
"create_list_input_label": "Zerrendaren izena [needs review]",
"create_list_input_placeholder": "adib. Asteko erosketa [needs review]",
"create_list_submit": "Sortu [needs review]",
"create_list_suggestion_chip": "Iradokizuna: {title} [needs review]",
"create_list_auto_numbered_toast": "«{title}» bezala sortua [needs review]",
"manage_list_titles_section_title": "Iradokitako izenburuak [needs review]",
"manage_list_titles_blurb": "Aurrekonfiguratu zerrenda berrientzat lehenetsitako izenburu bat eta mantendu iradokizun zerrenda bat. [needs review]",
"manage_default_list_title_label": "Lehenetsitako izenburua [needs review]",
"manage_default_list_title_placeholder": "adib. Asteko erosketa [needs review]",
"manage_default_list_title_clear": "Garbitu [needs review]",
"manage_list_titles_empty": "Oraindik ez dago iradokitako izenbururik. [needs review]",
"manage_list_titles_add_button": "Izenburua gehitu [needs review]",
"manage_list_titles_add_modal_title": "Iradokitako izenburua gehitu [needs review]",
"manage_list_titles_add_name_label": "Izenburua [needs review]",
"manage_list_titles_add_name_placeholder": "adib. Erosketa [needs review]",
"manage_list_titles_add_save": "Gehitu [needs review]",
"manage_list_titles_remove": "Ezabatu [needs review]",
"manage_list_titles_readonly": "Administratzaileek soilik kudea ditzakete izenburu hauek. [needs review]"
}

View File

@@ -1,7 +1,7 @@
{
"$schema": "https://inlang.com/schema/project-settings",
"sourceLanguageTag": "en",
"languageTags": ["en", "es"],
"languageTags": ["en", "es", "eu"],
"modules": [
"https://cdn.jsdelivr.net/npm/@inlang/plugin-message-format@4/dist/index.js",
"https://cdn.jsdelivr.net/npm/@inlang/plugin-m-function-matcher@1/dist/index.js"

90
scripts/check-locales.mjs Normal file
View File

@@ -0,0 +1,90 @@
#!/usr/bin/env node
/**
* Locale key parity check (Fase 20.2.2).
*
* Compares the JSON message bundles under apps/web/messages/ against the
* source-of-truth bundle (`en.json`). Fails (exit 1) if any of the
* non-source locales has missing or extra keys.
*
* The `$schema` property is intentionally ignored — it's a JSON-Schema
* pointer, not a translatable message.
*
* Usage:
* node scripts/check-locales.mjs # check all
* node scripts/check-locales.mjs eu # check only eu
*
* Run via the Justfile recipe `check-locales` or `pnpm -F @colectivo/web …`
* — kept dependency-free on purpose so it works at any tooling level.
*/
import { readFileSync, readdirSync } from 'node:fs';
import { join } from 'node:path';
import { fileURLToPath } from 'node:url';
import { dirname } from 'node:path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const MESSAGES_DIR = join(__dirname, '..', 'apps', 'web', 'messages');
const SOURCE_LOCALE = 'en';
const IGNORED_KEYS = new Set(['$schema']);
function loadLocale(name) {
const path = join(MESSAGES_DIR, `${name}.json`);
const raw = readFileSync(path, 'utf8');
const obj = JSON.parse(raw);
const keys = new Set(Object.keys(obj).filter((k) => !IGNORED_KEYS.has(k)));
return { name, path, keys, obj };
}
function diffSets(reference, candidate) {
const missing = [];
const extra = [];
for (const k of reference) {
if (!candidate.has(k)) missing.push(k);
}
for (const k of candidate) {
if (!reference.has(k)) extra.push(k);
}
return { missing, extra };
}
function main() {
const filter = process.argv.slice(2);
const allFiles = readdirSync(MESSAGES_DIR).filter((f) => f.endsWith('.json'));
const allLocales = allFiles.map((f) => f.replace(/\.json$/, ''));
if (!allLocales.includes(SOURCE_LOCALE)) {
console.error(`Source locale ${SOURCE_LOCALE}.json not found in ${MESSAGES_DIR}`);
process.exit(2);
}
const source = loadLocale(SOURCE_LOCALE);
const targets = allLocales
.filter((l) => l !== SOURCE_LOCALE)
.filter((l) => filter.length === 0 || filter.includes(l))
.map(loadLocale);
let failed = false;
for (const t of targets) {
const { missing, extra } = diffSets(source.keys, t.keys);
if (missing.length === 0 && extra.length === 0) {
console.log(`${t.name}: ${t.keys.size} keys match ${SOURCE_LOCALE}`);
continue;
}
failed = true;
console.error(`${t.name}: key drift vs ${SOURCE_LOCALE}`);
if (missing.length > 0) {
console.error(` missing (${missing.length}):`);
for (const k of missing) console.error(` - ${k}`);
}
if (extra.length > 0) {
console.error(` extra (${extra.length}):`);
for (const k of extra) console.error(` + ${k}`);
}
}
if (failed) {
process.exit(1);
}
}
main();