Files
ermnvldmr.com/packages/i18n/src/lib/path.ts
T
deytenit b84ef775b8 Various build shenenigans (#5)
This PR extends the build pipeline of the www service to support
locale-prefixed static builds (EN/RU) with build-time SSG output
injection, while also refactoring UI typography to a tokenized Tailwind
v4 @theme-driven approach.

Changes:

- Add build-time SSG plugin to @ermnvldmr/rsbuild-config and wire
multi-locale builds (/en/, /ru/) into services/www.
- Introduce new @ermnvldmr/i18n package (locale constants, path helpers,
keysets, pluralization) and apply it to www navigation/text.
- Refactor ui typography to a shared getTypographyClassNames utility +
Tailwind token definitions, with stl/cn updated for correct
Tailwind-merge behavior.
2026-03-16 00:00:20 +03:00

58 lines
2.4 KiB
TypeScript

import { LOCALE, LOCALES, type Locale } from './locale.js';
/**
* Resolves any href value to its locale-aware form.
*
* Only absolute internal paths (starting with `/`) are rewritten; everything else
* (external URLs, mailto/tel, relative paths, hash anchors) passes through unchanged.
* The function is idempotent: paths already carrying any known locale prefix are returned as-is.
*
* Works identically in dev and production: the dev server is configured with
* `server.base = /${LOCALE}` via `localeRsbuildConfig`.
*
* @param href - The href value to resolve.
* @returns The locale-prefixed href, or the original value when no rewrite is needed.
* @example
* // LOCALE = 'en'
* localePath('/articles') // → '/en/articles'
* localePath('/') // → '/en/'
* localePath('/en/articles') // → '/en/articles' (idempotent)
* localePath('https://github.com') // → 'https://github.com' (external)
* localePath('mailto:a@b.com') // → 'mailto:a@b.com'
* localePath('#section') // → '#section'
*/
export function localePath(href: string): string;
export function localePath(href: null): null;
export function localePath(href: undefined): undefined;
export function localePath(href: string | undefined): string | undefined;
export function localePath(href: string | null): string | null;
export function localePath(href: string | null | undefined): string | null | undefined;
export function localePath(href: string | null | undefined): string | null | undefined {
if (href == null) return href;
if (!href.startsWith('/')) return href;
if (LOCALES.some((l) => href === `/${l}` || href === `/${l}/` || href.startsWith(`/${l}/`))) {
return href;
}
if (href === '/') return `/${LOCALE}/`;
return `/${LOCALE}${href}`;
}
/**
* Builds a URL for a specific locale given the current locale-prefixed URL.
*
* @param currentPath - The current page path, e.g. `/en/articles`.
* @param locale - The target locale.
* @returns The equivalent path for `locale`, e.g. `/ru/articles`.
* @example
* localeHref('/en/articles', 'ru') // → '/ru/articles'
* localeHref('/en/', 'ru') // → '/ru/'
*/
export function localeHref(currentPath: string, locale: Locale): string {
const localePrefix = new RegExp(`^\\/(${LOCALES.join('|')})(.*)`);
const match = localePrefix.exec(currentPath);
if (match) {
return `/${locale}${match[2] || '/'}`;
}
return `/${locale}${currentPath}`;
}