mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-14 20:01:09 +02:00
feat(scripts): validate:i18n-hardcoded — ratcheting baseline check
Stoppt das Wachsen des 1877-String-Backlogs hardgecodeter deutscher User-facing Strings in .svelte Files. Per-file Count vs. committed Baseline; Datei darf NIE über ihrer Baseline liegen, neue Files müssen mit 0 Verstößen starten. - Erkennt: placeholder/title/aria-label/label/alt mit Umlauten, Text-Content `>Großbuchstabe…<` (ohne Interpolation). - Aktuelle Baseline: 1877 Verstöße in 428 Files; jeder Fix ratchet't den erlaubten Wert nach unten. - Lokales Update nach gewolltem Wachstum: `pnpm run validate:i18n-hardcoded -- --update`. - In validate:all + CI verdrahtet. - Drift-Test bestätigt: ein zusätzlicher umlaut-Placeholder lässt die Datei "2 (was 1, +1)" failen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
d8feef1149
commit
8b9fbd2e1c
3 changed files with 557 additions and 1 deletions
430
scripts/i18n-hardcoded-baseline.json
Normal file
430
scripts/i18n-hardcoded-baseline.json
Normal file
|
|
@ -0,0 +1,430 @@
|
|||
{
|
||||
"apps/mana/apps/web/src/lib/components/admin/ProjectDataCard.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/admin/QuickLinks.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/admin/UserTable.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/ai/AiDebugBlock.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/ai/MissionGrantDialog.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/ai/MissionInputPicker.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/dashboard/DashboardGrid.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/dashboard/TilePanel.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/dashboard/widgets/CardsProgressWidget.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/components/dashboard/widgets/MusicLibraryWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/DetailViewShell.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/KeyboardShortcutsModal.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/landing/LandingEditor.svelte": 16,
|
||||
"apps/mana/apps/web/src/lib/components/layout/SpaceCreateDialog.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/components/layout/SpaceSwitcher.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/links/LinkedItems.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/my-data/DeleteConfirmationModal.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/components/my-data/ExportImportPanel.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/components/my-data/QRExportModal.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/components/observatory/SeenplatteScene.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/observatory/ui/DetailPanel.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/observatory/ui/LakeCard.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/observatory/ui/RiverCard.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/observatory/ui/TrendsChart.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/page-carousel/PageCarousel.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/profile/ChangePasswordModal.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/components/profile/DeleteAccountModal.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/components/profile/EditProfileModal.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/components/settings/AiSettings.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/settings/ByokKeysManager.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/components/settings/sections/GeneralSection.svelte": 13,
|
||||
"apps/mana/apps/web/src/lib/components/settings/sections/MyDataSection.svelte": 16,
|
||||
"apps/mana/apps/web/src/lib/components/settings/sections/SyncSection.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/components/settings/sections/TagPresetsSection.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/components/settings/sections/VaultSection.svelte": 10,
|
||||
"apps/mana/apps/web/src/lib/components/shell/ModuleShell.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/components/SuggestionToast.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/voice/VoiceCaptureBar.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/wallpaper/WallpaperPicker.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/components/workbench/AppPage.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/components/workbench/AppPagePicker.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/workbench/SceneAppBar.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/components/workbench/scenes/BindAgentDialog.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/components/workbench/ScopeEmptyState.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/admin/tabs/OverviewTab.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/admin/tabs/SystemTab.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/admin/tabs/UserDataTab.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/modules/admin/tabs/UsersTab.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/ai-agents/ListView.svelte": 23,
|
||||
"apps/mana/apps/web/src/lib/modules/ai-health/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/ai-insights/ListView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/ai-missions/ListView.svelte": 22,
|
||||
"apps/mana/apps/web/src/lib/modules/ai-workbench/ListView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/api-keys/ListView.svelte": 11,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/components/AddUrlForm.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/components/HighlightMenu.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/components/HomeSectionSources.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/components/HomeSectionWeiterlesen.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/components/QuickAddInput.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/views/DetailView.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/views/HighlightsView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/articles/widgets/ArticlesUnreadWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/automations/ListView.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/CalorieWeightChart.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/ExercisePicker.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/ExerciseProgressionChart.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/PhaseManager.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/RoutineManager.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/SetRow.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/body/components/WeightChart.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/body/widgets/BodyStatsWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/audience/AudienceBuilder.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/components/SettingsForm.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/editor/Editor.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/ListView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/views/ComposeView.svelte": 11,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/views/DetailView.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/modules/broadcast/widgets/BroadcastsWidget.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/calc/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/AgendaView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/CalendarHeader.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/CustomRecurrenceBuilder.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/DateStrip.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/EventCard.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/EventDetailModal.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/EventForm.svelte": 10,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/MiniCalendar.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/QuickEventPopover.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/components/SlotSuggestions.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/calendar/views/DetailView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/cards/components/CreateDeckModal.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/cards/views/DetailView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/chat/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/chat/views/DetailView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/citycorners/views/DetailView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/BatchPanelEditor.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/CharacterPicker.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/PanelEditor.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/PanelModelPicker.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/PanelStrip.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/ReferenceInputPicker.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/StoryboardSuggester.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/StoryCard.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/components/StoryForm.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/views/DetailView.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/comic/views/ListView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/companion/components/CompanionChat.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/companion/components/RitualRunner.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/companion/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/complexity/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/contacts/components/pages/ContactPage.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/contacts/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/contacts/views/DetailView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/context/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/ActiveTimerWidget.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/NutritionProgressWidget.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/PlantWateringWidget.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/QuoteOfTheDayWidget.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/RecentChatsWidget.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/RecentContactsWidget.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/TasksTodayWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/core/widgets/UpcomingEventsWidget.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/credits/ListView.svelte": 25,
|
||||
"apps/mana/apps/web/src/lib/modules/dreams/ListView.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/dreams/views/SymbolDetailView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/drink/ListView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/BringListEditor.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/DiscoveredEventCard.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/DiscoverySetup.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/DiscoveryTab.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/EventCard.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/GuestListEditor.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/PublicRsvpList.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/RegionPicker.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/RsvpSummary.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/events/components/SourceManager.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/events/ListView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/events/views/DetailView.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/finance/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/firsts/ListView.svelte": 15,
|
||||
"apps/mana/apps/web/src/lib/modules/goals/GoalEditor.svelte": 15,
|
||||
"apps/mana/apps/web/src/lib/modules/goals/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/guides/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/guides/views/DetailView.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/habits/components/HabitDetail.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/habits/components/HabitForm.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/habits/ListView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/inventory/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/inventory/views/DetailView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/components/ClientPicker.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/components/InvoiceForm.svelte": 10,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/components/LinesEditor.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/components/SenderProfileForm.svelte": 14,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/components/SendModal.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/views/DetailView.svelte": 18,
|
||||
"apps/mana/apps/web/src/lib/modules/invoices/widgets/InvoicesOpenWidget.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/journal/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/kontext/KontextView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/library/components/EntryForm.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/library/components/ProgressControls.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/library/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/library/views/DetailView.svelte": 15,
|
||||
"apps/mana/apps/web/src/lib/modules/library/views/GridView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/mail/ListView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/meditate/components/SessionPlayer.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/meditate/components/StatsOverview.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/meditate/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/memoro/views/DetailView.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/mood/components/QuickLog.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/mood/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/moodlit/components/mood/CreateMoodDialog.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/music/ListView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/music/views/DetailView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/myday/ListView.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/news-research/ListView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/news/ListView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/news/widgets/NewsUnreadWidget.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/notes/ListView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/photos/components/albums/CreateAlbumModal.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/photos/components/filters/FilterBar.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/photos/components/gallery/PhotoDetailModal.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/modules/photos/ListView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/picture/components/ReferenceImagePicker.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/picture/ListView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/places/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/places/views/DetailView.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/plants/views/DetailView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/playground/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/presi/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/presi/views/DetailView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/components/MeImageSlotCard.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/components/MeImageTile.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/ContextFreeform.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/ContextInterview.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/ContextOverview.svelte": 35,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/profile/MeImagesView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/questions/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/questions/views/DetailView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/quiz/EditView.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/quiz/ListView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/quiz/PlayView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/quotes/views/DetailView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/recipes/ListView.svelte": 14,
|
||||
"apps/mana/apps/web/src/lib/modules/research-lab/components/CompareColumn.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/research-lab/ListView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/rituals/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/components/AchievementCelebration.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/components/AddSkillModal.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/components/AddXpModal.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/components/EditSkillModal.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/components/LevelUpCelebration.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/components/StatsOverview.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/skilltree/views/DetailView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/sleep/components/MorningLog.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/sleep/ListView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/spaces/ListView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/spiral/ListView.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/storage/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/storage/views/DetailView.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/stretch/components/AssessmentWizard.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/stretch/components/ReminderManager.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/stretch/components/RoutineCreator.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/stretch/components/SessionHistory.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/stretch/components/SessionPlayer.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/stretch/ListView.svelte": 13,
|
||||
"apps/mana/apps/web/src/lib/modules/themes/ListView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/times/components/clock/CircularProgress.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/times/components/clock/WorldMap.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/times/components/EntryForm.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/times/components/QuickStart.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/times/views/DetailView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/components/board-views/ViewEditorModal.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/components/form/TagSelector.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/components/pages/PageEditBar.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/components/pages/PagePicker.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/components/pages/TodoPage.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/components/SyncIndicator.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/todo/views/DetailView.svelte": 8,
|
||||
"apps/mana/apps/web/src/lib/modules/uload/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/uload/views/DetailView.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentForm.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/components/GarmentTryOnButton.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/components/OutfitComposer.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/components/TryOnButton.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/components/TryOnModelPicker.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailGarmentView.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/views/DetailOutfitView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/views/GridView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wardrobe/views/OutfitsView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/BlockInspector.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/DomainsSection.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/GalleryInspector.svelte": 9,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/ImageInspector.svelte": 13,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/InsertPalette.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/PageList.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/PublishBar.svelte": 4,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/RollbackDialog.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/SiteSettingsDialog.svelte": 11,
|
||||
"apps/mana/apps/web/src/lib/modules/website/components/TemplatePicker.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/website/ListView.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/website/views/EditorView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/website/views/SubmissionsView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/components/CurrentConditions.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/components/HourlyForecast.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/components/LocationPicker.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/components/NowcastBar.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/components/SourceComparison.svelte": 7,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/components/WeatherAlerts.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/wetter/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/who/ListView.svelte": 5,
|
||||
"apps/mana/apps/web/src/lib/modules/who/views/PlayView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/wishes/ListView.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/wishes/views/DetailView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/BriefingForm.svelte": 11,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/ExportMenu.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/ReferencePicker.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/RefinementPanel.svelte": 12,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/StyleForm.svelte": 2,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/VersionEditor.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/components/VersionHistory.svelte": 1,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/views/DetailView.svelte": 6,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/views/ListView.svelte": 3,
|
||||
"apps/mana/apps/web/src/lib/modules/writing/views/StylesView.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/admin/+layout.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/admin/user-data/[userId]/+page.svelte": 19,
|
||||
"apps/mana/apps/web/src/routes/(app)/agents/templates/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/api-keys/+page.svelte": 14,
|
||||
"apps/mana/apps/web/src/routes/(app)/articles/settings/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/broadcasts/[id]/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/broadcasts/[id]/edit/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/broadcasts/new/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/calc/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/calc/standard/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/calendar/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/calendar/calendars/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/calendar/event/[id]/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/cards/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/cards/decks/[id]/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/cards/decks/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/cards/explore/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/cards/progress/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/chat/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/chat/archive/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/chat/templates/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/citycorners/cities/[slug]/+layout.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/comic/new/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/companion/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/contacts/[id]/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/contacts/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/context/+page.svelte": 10,
|
||||
"apps/mana/apps/web/src/routes/(app)/context/documents/[id]/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/context/documents/+page.svelte": 5,
|
||||
"apps/mana/apps/web/src/routes/(app)/context/spaces/[id]/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/context/spaces/+page.svelte": 5,
|
||||
"apps/mana/apps/web/src/routes/(app)/finance/+page.svelte": 10,
|
||||
"apps/mana/apps/web/src/routes/(app)/food/[id]/+page.svelte": 10,
|
||||
"apps/mana/apps/web/src/routes/(app)/food/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/food/add/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/food/goals/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/gifts/+page.svelte": 15,
|
||||
"apps/mana/apps/web/src/routes/(app)/gifts/redeem/[code]/+page.svelte": 8,
|
||||
"apps/mana/apps/web/src/routes/(app)/gifts/redeem/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/guides/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/habits/[id]/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/habits/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/categories/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/collections/[id]/+page.svelte": 5,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/collections/[id]/edit/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/collections/new/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/items/[id]/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/locations/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/inventory/search/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/invoices/[id]/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/invoices/[id]/edit/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/invoices/new/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/invoices/settings/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/library/entry/[id]/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/llm-test/+page.svelte": 29,
|
||||
"apps/mana/apps/web/src/routes/(app)/meditate/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/meditate/history/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/memoro/[id]/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/memoro/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/memoro/archive/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/memoro/tags/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/moodlit/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/moodlit/moods/+page.svelte": 9,
|
||||
"apps/mana/apps/web/src/routes/(app)/moodlit/sequences/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/music/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/music/library/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/music/playlists/[id]/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/music/playlists/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/music/projects/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/news-research/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/news/[id]/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/news/+page.svelte": 10,
|
||||
"apps/mana/apps/web/src/routes/(app)/news/add/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/news/preferences/+page.svelte": 8,
|
||||
"apps/mana/apps/web/src/routes/(app)/news/saved/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/news/sources/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/notes/[id]/+page.svelte": 5,
|
||||
"apps/mana/apps/web/src/routes/(app)/notes/+page.svelte": 8,
|
||||
"apps/mana/apps/web/src/routes/(app)/observatory/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/onboarding/+layout.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/onboarding/look/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/onboarding/name/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/onboarding/templates/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/organizations/[id]/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/organizations/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/photos/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/photos/albums/[id]/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/photos/albums/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/photos/favorites/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/photos/upload/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/picture/archive/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/picture/board/[id]/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/picture/board/+page.svelte": 5,
|
||||
"apps/mana/apps/web/src/routes/(app)/picture/generate/+page.svelte": 5,
|
||||
"apps/mana/apps/web/src/routes/(app)/plants/tags/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/playground/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/presi/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/presi/deck/[id]/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/presi/present/[id]/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/questions/[id]/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/questions/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/questions/collections/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/questions/new/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/skilltree/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/skilltree/achievements/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/skilltree/tree/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/storage/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/storage/favorites/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/storage/files/[folderId]/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/storage/files/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/storage/search/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/storage/trash/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/tags/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/teams/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/timeline/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/timeline/analytics/+page.svelte": 11,
|
||||
"apps/mana/apps/web/src/routes/(app)/times/clients/[id]/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(app)/times/clock/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/times/projects/[id]/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/(app)/todo/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/(app)/todo/settings/+page.svelte": 13,
|
||||
"apps/mana/apps/web/src/routes/(app)/uload/+page.svelte": 21,
|
||||
"apps/mana/apps/web/src/routes/(app)/uload/analytics/[id]/+page.svelte": 20,
|
||||
"apps/mana/apps/web/src/routes/(app)/uload/links/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/(app)/uload/settings/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/(app)/uload/tags/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/wardrobe/compose/[[outfitId]]/+page.svelte": 4,
|
||||
"apps/mana/apps/web/src/routes/(app)/wetter/+page.svelte": 2,
|
||||
"apps/mana/apps/web/src/routes/(auth)/reset-password/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/+error.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/accept-invitation/+page.svelte": 7,
|
||||
"apps/mana/apps/web/src/routes/auth/callback/+page.svelte": 3,
|
||||
"apps/mana/apps/web/src/routes/auth/reset-password/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/g/[code]/+page.svelte": 6,
|
||||
"apps/mana/apps/web/src/routes/rsvp/[token]/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/status/+page.svelte": 1,
|
||||
"apps/mana/apps/web/src/routes/welcome/+page.svelte": 6
|
||||
}
|
||||
125
scripts/validate-no-hardcoded-strings.mjs
Normal file
125
scripts/validate-no-hardcoded-strings.mjs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#!/usr/bin/env node
|
||||
/**
|
||||
* Ratcheting validator for hardcoded German user-facing strings in
|
||||
* apps/mana/apps/web Svelte components. Looks for German-looking text
|
||||
* in attribute values (placeholder, title, aria-label, label, alt) and
|
||||
* in text content, and compares per-file counts against a committed
|
||||
* baseline.
|
||||
*
|
||||
* Every file's current count must be ≤ its baseline count. New files
|
||||
* (not in baseline) must have 0 violations. The baseline can only
|
||||
* shrink — fixing strings is rewarded, adding new ones fails CI.
|
||||
*
|
||||
* The validator is intentionally coarse: the goal is to stop the 1877-
|
||||
* string backlog from growing while it's being whittled down, not to
|
||||
* catch every translation miss perfectly.
|
||||
*
|
||||
* Usage:
|
||||
* node scripts/validate-no-hardcoded-strings.mjs # check
|
||||
* node scripts/validate-no-hardcoded-strings.mjs --update # rewrite baseline
|
||||
*/
|
||||
|
||||
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join, relative } from 'node:path';
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const REPO_ROOT = join(__dirname, '..');
|
||||
const BASELINE_PATH = join(__dirname, 'i18n-hardcoded-baseline.json');
|
||||
const SCAN_GLOB = 'apps/mana/apps/web/src/**/*.svelte';
|
||||
|
||||
const PATTERNS = [
|
||||
/placeholder="([^"{}]*[äöüÄÖÜß][^"{}]*)"/g,
|
||||
/title="([^"{}]*[äöüÄÖÜß][^"{}]*)"/g,
|
||||
/aria-label="([^"{}]*[äöüÄÖÜß][^"{}]*)"/g,
|
||||
/label="([^"{}]*[äöüÄÖÜß][^"{}]*)"/g,
|
||||
/alt="([^"{}]*[äöüÄÖÜß][^"{}]*)"/g,
|
||||
/>([A-ZÄÖÜ][a-zäöüß][a-zäöüßÄÖÜA-Z ,.!?]{2,40})</g,
|
||||
];
|
||||
|
||||
function scan() {
|
||||
const files = execSync(`git ls-files '${SCAN_GLOB}'`, { cwd: REPO_ROOT })
|
||||
.toString()
|
||||
.trim()
|
||||
.split('\n')
|
||||
.filter(Boolean);
|
||||
|
||||
const counts = {};
|
||||
for (const f of files) {
|
||||
let src;
|
||||
try {
|
||||
src = readFileSync(join(REPO_ROOT, f), 'utf8');
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
let n = 0;
|
||||
for (const p of PATTERNS) for (const _ of src.matchAll(p)) n++;
|
||||
if (n > 0) counts[f] = n;
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
function loadBaseline() {
|
||||
if (!existsSync(BASELINE_PATH)) return {};
|
||||
return JSON.parse(readFileSync(BASELINE_PATH, 'utf8'));
|
||||
}
|
||||
|
||||
function main() {
|
||||
const update = process.argv.includes('--update');
|
||||
const current = scan();
|
||||
const currentTotal = Object.values(current).reduce((a, b) => a + b, 0);
|
||||
|
||||
if (update) {
|
||||
const sorted = Object.fromEntries(
|
||||
Object.entries(current).sort(([a], [b]) => a.localeCompare(b))
|
||||
);
|
||||
writeFileSync(BASELINE_PATH, JSON.stringify(sorted, null, 2) + '\n');
|
||||
console.log(
|
||||
`✓ Baseline updated: ${currentTotal} violations across ${Object.keys(current).length} files.`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const baseline = loadBaseline();
|
||||
const baselineTotal = Object.values(baseline).reduce((a, b) => a + b, 0);
|
||||
const violations = [];
|
||||
|
||||
for (const [file, n] of Object.entries(current)) {
|
||||
const b = baseline[file] ?? 0;
|
||||
if (n > b) violations.push({ file, current: n, baseline: b, delta: n - b });
|
||||
}
|
||||
|
||||
if (violations.length > 0) {
|
||||
console.error(
|
||||
`\n✗ Hardcoded-string check FAILED — ${violations.length} file(s) exceed baseline:\n`
|
||||
);
|
||||
for (const v of violations.slice(0, 20)) {
|
||||
console.error(` ${v.file}: ${v.current} (was ${v.baseline}, +${v.delta})`);
|
||||
}
|
||||
if (violations.length > 20) console.error(` … +${violations.length - 20} more`);
|
||||
console.error(
|
||||
`\nYou added user-facing German strings to .svelte files without\n` +
|
||||
`going through \$_('namespace.key'). Move them into locales/ or\n` +
|
||||
`translate them inline, then re-run validate:i18n-hardcoded.\n` +
|
||||
`If the additions are intentional (e.g. an untranslated dev-only\n` +
|
||||
`page), run: pnpm run validate:i18n-hardcoded -- --update\n`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Dropped below baseline? Tell the user so they can ratchet.
|
||||
const shrunk = Object.keys(baseline).filter((f) => (current[f] ?? 0) < baseline[f]).length;
|
||||
const cleaned = Object.keys(baseline).filter((f) => !(f in current)).length;
|
||||
|
||||
console.log(
|
||||
`✓ Hardcoded strings: ${currentTotal} violations across ${Object.keys(current).length} files ` +
|
||||
`(baseline ${baselineTotal}).` +
|
||||
(shrunk || cleaned
|
||||
? `\n ${shrunk} file(s) shrunk, ${cleaned} file(s) fully cleaned — ` +
|
||||
`run 'pnpm run validate:i18n-hardcoded -- --update' to ratchet.`
|
||||
: '')
|
||||
);
|
||||
}
|
||||
|
||||
main();
|
||||
Loading…
Add table
Add a link
Reference in a new issue