Files
twenty/packages/twenty-shared/src/utils/validation/normalizeLocale.ts
T
Félix Malfait 41dd9856e6 fix(twenty-front): fix tsconfig to properly typecheck all files with tsgo (#17380)
## Summary

This PR fixes the `tsconfig` setup in `twenty-front` so that `tsgo -p
tsconfig.json` properly type-checks all files.

### Root Cause

The previous setup used TypeScript project references with `files: []`
in the main `tsconfig.json`. When running `tsgo -p tsconfig.json`, this
checks nothing because `tsgo` requires the `-b` (build) flag for project
references, but the configs weren't set up for composite mode.

### Changes

**Simplified tsconfig architecture (4 files → 2):**
- `tsconfig.json` - All files (dev, tests, stories) for
typecheck/IDE/lint
- `tsconfig.build.json` - Production files only (excludes tests/stories)

**Removed redundant configs:**
- `tsconfig.dev.json`
- `tsconfig.spec.json` 
- `tsconfig.storybook.json`

**Updated references:**
- `jest.config.mjs` → uses `tsconfig.json`
- `eslint.config.mjs` → uses `tsconfig.json`
- `vite.config.ts` → uses `tsconfig.json` for dev

**Type fixes (pre-existing errors revealed by proper typechecking):**
- Made `applicationId` optional in `FieldMetadataItem` and
`ObjectMetadataItem`
- Added missing `navigationMenuItem` translation
- Added `objectLabelSingular` to Search GraphQL query
- Fixed `sortMorphItems.test.ts` mock data

## Test plan

- [ ] Run `npx nx typecheck twenty-front` - should pass
- [ ] Run `npx nx lint twenty-front` - should work
- [ ] Run `npx nx test twenty-front` - should work
- [ ] Run `npx nx build twenty-front` - should work
- [ ] Verify IDE type checking works correctly
2026-01-23 11:22:23 +01:00

50 lines
1.5 KiB
TypeScript

import {
APP_LOCALES,
type AppLocale,
} from '@/translations/constants/AppLocales';
import { SOURCE_LOCALE } from '@/translations/constants/SourceLocale';
// Maps language codes to full locale keys in APP_LOCALES
// Example: 'fr' -> 'fr-FR', 'en' -> 'en'
const languageToLocaleMap = Object.keys(APP_LOCALES).reduce<
Record<string, string>
>((map, locale) => {
const language = locale.split('-')[0].toLowerCase();
// Only add to the map if not already added or if the current locale is the source locale
// This ensures language codes map to their full locale version (e.g., 'es' -> 'es-ES')
// but preserves 'en' -> 'en' since it's the source locale
if (!map[language] || locale === SOURCE_LOCALE) {
map[language] = locale;
}
return map;
}, {});
export const normalizeLocale = (value: string | null): AppLocale => {
if (value === null) {
return SOURCE_LOCALE;
}
// Direct match in our supported locales
if (value in APP_LOCALES) {
return value as AppLocale;
}
// Try case-insensitive match (e.g., 'fr-fr' -> 'fr-FR')
const caseInsensitiveMatch = Object.keys(APP_LOCALES).find(
(locale) => locale.toLowerCase() === value.toLowerCase(),
);
if (caseInsensitiveMatch) {
return caseInsensitiveMatch as AppLocale;
}
// Try matching just the language part (e.g., 'fr' -> 'fr-FR')
const languageCode = value?.trim() ? value.split('-')[0].toLowerCase() : '';
if (languageToLocaleMap[languageCode]) {
return languageToLocaleMap[languageCode] as AppLocale;
}
return SOURCE_LOCALE;
};